1 // SPDX-License-Identifier: GPL-2.0-only 2 // Copyright (C) 2017 Broadcom 3 4 #include <linux/delay.h> 5 #include <linux/extcon-provider.h> 6 #include <linux/gpio.h> 7 #include <linux/gpio/consumer.h> 8 #include <linux/init.h> 9 #include <linux/interrupt.h> 10 #include <linux/io.h> 11 #include <linux/iopoll.h> 12 #include <linux/irq.h> 13 #include <linux/mfd/syscon.h> 14 #include <linux/module.h> 15 #include <linux/of.h> 16 #include <linux/of_address.h> 17 #include <linux/phy/phy.h> 18 #include <linux/platform_device.h> 19 #include <linux/regmap.h> 20 #include <linux/slab.h> 21 #include <linux/workqueue.h> 22 23 #define ICFG_DRD_AFE 0x0 24 #define ICFG_MISC_STAT 0x18 25 #define ICFG_DRD_P0CTL 0x1C 26 #define ICFG_STRAP_CTRL 0x20 27 #define ICFG_FSM_CTRL 0x24 28 29 #define ICFG_DEV_BIT BIT(2) 30 #define IDM_RST_BIT BIT(0) 31 #define AFE_CORERDY_VDDC BIT(18) 32 #define PHY_PLL_RESETB BIT(15) 33 #define PHY_RESETB BIT(14) 34 #define PHY_PLL_LOCK BIT(0) 35 36 #define DRD_DEV_MODE BIT(20) 37 #define OHCI_OVRCUR_POL BIT(11) 38 #define ICFG_OFF_MODE BIT(6) 39 #define PLL_LOCK_RETRY 1000 40 41 #define EVT_DEVICE 0 42 #define EVT_HOST 1 43 44 #define DRD_HOST_MODE (BIT(2) | BIT(3)) 45 #define DRD_DEVICE_MODE (BIT(4) | BIT(5)) 46 #define DRD_HOST_VAL 0x803 47 #define DRD_DEV_VAL 0x807 48 #define GPIO_DELAY 20 49 50 struct ns2_phy_data; 51 struct ns2_phy_driver { 52 void __iomem *icfgdrd_regs; 53 void __iomem *idmdrd_rst_ctrl; 54 void __iomem *crmu_usb2_ctrl; 55 void __iomem *usb2h_strap_reg; 56 struct ns2_phy_data *data; 57 struct extcon_dev *edev; 58 struct gpio_desc *vbus_gpiod; 59 struct gpio_desc *id_gpiod; 60 int id_irq; 61 int vbus_irq; 62 unsigned long debounce_jiffies; 63 struct delayed_work wq_extcon; 64 }; 65 66 struct ns2_phy_data { 67 struct ns2_phy_driver *driver; 68 struct phy *phy; 69 int new_state; 70 }; 71 72 static const unsigned int usb_extcon_cable[] = { 73 EXTCON_USB, 74 EXTCON_USB_HOST, 75 EXTCON_NONE, 76 }; 77 78 static inline int pll_lock_stat(u32 usb_reg, int reg_mask, 79 struct ns2_phy_driver *driver) 80 { 81 u32 val; 82 83 return readl_poll_timeout_atomic(driver->icfgdrd_regs + usb_reg, 84 val, (val & reg_mask), 1, 85 PLL_LOCK_RETRY); 86 } 87 88 static int ns2_drd_phy_init(struct phy *phy) 89 { 90 struct ns2_phy_data *data = phy_get_drvdata(phy); 91 struct ns2_phy_driver *driver = data->driver; 92 u32 val; 93 94 val = readl(driver->icfgdrd_regs + ICFG_FSM_CTRL); 95 96 if (data->new_state == EVT_HOST) { 97 val &= ~DRD_DEVICE_MODE; 98 val |= DRD_HOST_MODE; 99 } else { 100 val &= ~DRD_HOST_MODE; 101 val |= DRD_DEVICE_MODE; 102 } 103 writel(val, driver->icfgdrd_regs + ICFG_FSM_CTRL); 104 105 return 0; 106 } 107 108 static int ns2_drd_phy_poweroff(struct phy *phy) 109 { 110 struct ns2_phy_data *data = phy_get_drvdata(phy); 111 struct ns2_phy_driver *driver = data->driver; 112 u32 val; 113 114 val = readl(driver->crmu_usb2_ctrl); 115 val &= ~AFE_CORERDY_VDDC; 116 writel(val, driver->crmu_usb2_ctrl); 117 118 val = readl(driver->crmu_usb2_ctrl); 119 val &= ~DRD_DEV_MODE; 120 writel(val, driver->crmu_usb2_ctrl); 121 122 /* Disable Host and Device Mode */ 123 val = readl(driver->icfgdrd_regs + ICFG_FSM_CTRL); 124 val &= ~(DRD_HOST_MODE | DRD_DEVICE_MODE | ICFG_OFF_MODE); 125 writel(val, driver->icfgdrd_regs + ICFG_FSM_CTRL); 126 127 return 0; 128 } 129 130 static int ns2_drd_phy_poweron(struct phy *phy) 131 { 132 struct ns2_phy_data *data = phy_get_drvdata(phy); 133 struct ns2_phy_driver *driver = data->driver; 134 u32 extcon_event = data->new_state; 135 int ret; 136 u32 val; 137 138 if (extcon_event == EVT_DEVICE) { 139 writel(DRD_DEV_VAL, driver->icfgdrd_regs + ICFG_DRD_P0CTL); 140 141 val = readl(driver->idmdrd_rst_ctrl); 142 val &= ~IDM_RST_BIT; 143 writel(val, driver->idmdrd_rst_ctrl); 144 145 val = readl(driver->crmu_usb2_ctrl); 146 val |= (AFE_CORERDY_VDDC | DRD_DEV_MODE); 147 writel(val, driver->crmu_usb2_ctrl); 148 149 /* Bring PHY and PHY_PLL out of Reset */ 150 val = readl(driver->crmu_usb2_ctrl); 151 val |= (PHY_PLL_RESETB | PHY_RESETB); 152 writel(val, driver->crmu_usb2_ctrl); 153 154 ret = pll_lock_stat(ICFG_MISC_STAT, PHY_PLL_LOCK, driver); 155 if (ret < 0) { 156 dev_err(&phy->dev, "Phy PLL lock failed\n"); 157 return ret; 158 } 159 } else { 160 writel(DRD_HOST_VAL, driver->icfgdrd_regs + ICFG_DRD_P0CTL); 161 162 val = readl(driver->crmu_usb2_ctrl); 163 val |= AFE_CORERDY_VDDC; 164 writel(val, driver->crmu_usb2_ctrl); 165 166 ret = pll_lock_stat(ICFG_MISC_STAT, PHY_PLL_LOCK, driver); 167 if (ret < 0) { 168 dev_err(&phy->dev, "Phy PLL lock failed\n"); 169 return ret; 170 } 171 172 val = readl(driver->idmdrd_rst_ctrl); 173 val &= ~IDM_RST_BIT; 174 writel(val, driver->idmdrd_rst_ctrl); 175 176 /* port over current Polarity */ 177 val = readl(driver->usb2h_strap_reg); 178 val |= OHCI_OVRCUR_POL; 179 writel(val, driver->usb2h_strap_reg); 180 } 181 182 return 0; 183 } 184 185 static void connect_change(struct ns2_phy_driver *driver) 186 { 187 u32 extcon_event; 188 u32 val; 189 190 extcon_event = driver->data->new_state; 191 val = readl(driver->icfgdrd_regs + ICFG_FSM_CTRL); 192 193 switch (extcon_event) { 194 case EVT_DEVICE: 195 val &= ~(DRD_HOST_MODE | DRD_DEVICE_MODE); 196 writel(val, driver->icfgdrd_regs + ICFG_FSM_CTRL); 197 198 val = (val & ~DRD_HOST_MODE) | DRD_DEVICE_MODE; 199 writel(val, driver->icfgdrd_regs + ICFG_FSM_CTRL); 200 201 val = readl(driver->icfgdrd_regs + ICFG_DRD_P0CTL); 202 val |= ICFG_DEV_BIT; 203 writel(val, driver->icfgdrd_regs + ICFG_DRD_P0CTL); 204 break; 205 206 case EVT_HOST: 207 val &= ~(DRD_HOST_MODE | DRD_DEVICE_MODE); 208 writel(val, driver->icfgdrd_regs + ICFG_FSM_CTRL); 209 210 val = (val & ~DRD_DEVICE_MODE) | DRD_HOST_MODE; 211 writel(val, driver->icfgdrd_regs + ICFG_FSM_CTRL); 212 213 val = readl(driver->usb2h_strap_reg); 214 val |= OHCI_OVRCUR_POL; 215 writel(val, driver->usb2h_strap_reg); 216 217 val = readl(driver->icfgdrd_regs + ICFG_DRD_P0CTL); 218 val &= ~ICFG_DEV_BIT; 219 writel(val, driver->icfgdrd_regs + ICFG_DRD_P0CTL); 220 break; 221 222 default: 223 pr_err("Invalid extcon event\n"); 224 break; 225 } 226 } 227 228 static void extcon_work(struct work_struct *work) 229 { 230 struct ns2_phy_driver *driver; 231 int vbus; 232 int id; 233 234 driver = container_of(to_delayed_work(work), 235 struct ns2_phy_driver, wq_extcon); 236 237 id = gpiod_get_value_cansleep(driver->id_gpiod); 238 vbus = gpiod_get_value_cansleep(driver->vbus_gpiod); 239 240 if (!id && vbus) { /* Host connected */ 241 extcon_set_state_sync(driver->edev, EXTCON_USB_HOST, true); 242 pr_debug("Host cable connected\n"); 243 driver->data->new_state = EVT_HOST; 244 connect_change(driver); 245 } else if (id && !vbus) { /* Disconnected */ 246 extcon_set_state_sync(driver->edev, EXTCON_USB_HOST, false); 247 extcon_set_state_sync(driver->edev, EXTCON_USB, false); 248 pr_debug("Cable disconnected\n"); 249 } else if (id && vbus) { /* Device connected */ 250 extcon_set_state_sync(driver->edev, EXTCON_USB, true); 251 pr_debug("Device cable connected\n"); 252 driver->data->new_state = EVT_DEVICE; 253 connect_change(driver); 254 } 255 } 256 257 static irqreturn_t gpio_irq_handler(int irq, void *dev_id) 258 { 259 struct ns2_phy_driver *driver = dev_id; 260 261 queue_delayed_work(system_power_efficient_wq, &driver->wq_extcon, 262 driver->debounce_jiffies); 263 264 return IRQ_HANDLED; 265 } 266 267 static const struct phy_ops ops = { 268 .init = ns2_drd_phy_init, 269 .power_on = ns2_drd_phy_poweron, 270 .power_off = ns2_drd_phy_poweroff, 271 .owner = THIS_MODULE, 272 }; 273 274 static const struct of_device_id ns2_drd_phy_dt_ids[] = { 275 { .compatible = "brcm,ns2-drd-phy", }, 276 { } 277 }; 278 MODULE_DEVICE_TABLE(of, ns2_drd_phy_dt_ids); 279 280 static int ns2_drd_phy_probe(struct platform_device *pdev) 281 { 282 struct phy_provider *phy_provider; 283 struct device *dev = &pdev->dev; 284 struct ns2_phy_driver *driver; 285 struct ns2_phy_data *data; 286 int ret; 287 u32 val; 288 289 driver = devm_kzalloc(dev, sizeof(struct ns2_phy_driver), 290 GFP_KERNEL); 291 if (!driver) 292 return -ENOMEM; 293 294 driver->data = devm_kzalloc(dev, sizeof(struct ns2_phy_data), 295 GFP_KERNEL); 296 if (!driver->data) 297 return -ENOMEM; 298 299 driver->icfgdrd_regs = devm_platform_ioremap_resource_byname(pdev, "icfg"); 300 if (IS_ERR(driver->icfgdrd_regs)) 301 return PTR_ERR(driver->icfgdrd_regs); 302 303 driver->idmdrd_rst_ctrl = devm_platform_ioremap_resource_byname(pdev, "rst-ctrl"); 304 if (IS_ERR(driver->idmdrd_rst_ctrl)) 305 return PTR_ERR(driver->idmdrd_rst_ctrl); 306 307 driver->crmu_usb2_ctrl = devm_platform_ioremap_resource_byname(pdev, "crmu-ctrl"); 308 if (IS_ERR(driver->crmu_usb2_ctrl)) 309 return PTR_ERR(driver->crmu_usb2_ctrl); 310 311 driver->usb2h_strap_reg = devm_platform_ioremap_resource_byname(pdev, "usb2-strap"); 312 if (IS_ERR(driver->usb2h_strap_reg)) 313 return PTR_ERR(driver->usb2h_strap_reg); 314 315 /* create extcon */ 316 driver->id_gpiod = devm_gpiod_get(&pdev->dev, "id", GPIOD_IN); 317 if (IS_ERR(driver->id_gpiod)) { 318 dev_err(dev, "failed to get ID GPIO\n"); 319 return PTR_ERR(driver->id_gpiod); 320 } 321 driver->vbus_gpiod = devm_gpiod_get(&pdev->dev, "vbus", GPIOD_IN); 322 if (IS_ERR(driver->vbus_gpiod)) { 323 dev_err(dev, "failed to get VBUS GPIO\n"); 324 return PTR_ERR(driver->vbus_gpiod); 325 } 326 327 driver->edev = devm_extcon_dev_allocate(dev, usb_extcon_cable); 328 if (IS_ERR(driver->edev)) { 329 dev_err(dev, "failed to allocate extcon device\n"); 330 return -ENOMEM; 331 } 332 333 ret = devm_extcon_dev_register(dev, driver->edev); 334 if (ret < 0) { 335 dev_err(dev, "failed to register extcon device\n"); 336 return ret; 337 } 338 339 ret = gpiod_set_debounce(driver->id_gpiod, GPIO_DELAY * 1000); 340 if (ret < 0) 341 driver->debounce_jiffies = msecs_to_jiffies(GPIO_DELAY); 342 343 INIT_DELAYED_WORK(&driver->wq_extcon, extcon_work); 344 345 driver->id_irq = gpiod_to_irq(driver->id_gpiod); 346 if (driver->id_irq < 0) { 347 dev_err(dev, "failed to get ID IRQ\n"); 348 return driver->id_irq; 349 } 350 351 driver->vbus_irq = gpiod_to_irq(driver->vbus_gpiod); 352 if (driver->vbus_irq < 0) { 353 dev_err(dev, "failed to get ID IRQ\n"); 354 return driver->vbus_irq; 355 } 356 357 ret = devm_request_irq(dev, driver->id_irq, gpio_irq_handler, 358 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 359 "usb_id", driver); 360 if (ret < 0) { 361 dev_err(dev, "failed to request handler for ID IRQ\n"); 362 return ret; 363 } 364 365 ret = devm_request_irq(dev, driver->vbus_irq, gpio_irq_handler, 366 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 367 "usb_vbus", driver); 368 if (ret < 0) { 369 dev_err(dev, "failed to request handler for VBUS IRQ\n"); 370 return ret; 371 } 372 373 dev_set_drvdata(dev, driver); 374 375 /* Shutdown all ports. They can be powered up as required */ 376 val = readl(driver->crmu_usb2_ctrl); 377 val &= ~(AFE_CORERDY_VDDC | PHY_RESETB); 378 writel(val, driver->crmu_usb2_ctrl); 379 380 data = driver->data; 381 data->phy = devm_phy_create(dev, dev->of_node, &ops); 382 if (IS_ERR(data->phy)) { 383 dev_err(dev, "Failed to create usb drd phy\n"); 384 return PTR_ERR(data->phy); 385 } 386 387 data->driver = driver; 388 phy_set_drvdata(data->phy, data); 389 390 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 391 if (IS_ERR(phy_provider)) { 392 dev_err(dev, "Failed to register as phy provider\n"); 393 return PTR_ERR(phy_provider); 394 } 395 396 platform_set_drvdata(pdev, driver); 397 398 dev_info(dev, "Registered NS2 DRD Phy device\n"); 399 queue_delayed_work(system_power_efficient_wq, &driver->wq_extcon, 400 driver->debounce_jiffies); 401 402 return 0; 403 } 404 405 static struct platform_driver ns2_drd_phy_driver = { 406 .probe = ns2_drd_phy_probe, 407 .driver = { 408 .name = "bcm-ns2-usbphy", 409 .of_match_table = of_match_ptr(ns2_drd_phy_dt_ids), 410 }, 411 }; 412 module_platform_driver(ns2_drd_phy_driver); 413 414 MODULE_ALIAS("platform:bcm-ns2-drd-phy"); 415 MODULE_AUTHOR("Broadcom"); 416 MODULE_DESCRIPTION("Broadcom NS2 USB2 PHY driver"); 417 MODULE_LICENSE("GPL v2"); 418