1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * dwc3-rtk.c - Realtek DWC3 Specific Glue layer 4 * 5 * Copyright (C) 2023 Realtek Semiconductor Corporation 6 * 7 */ 8 9 #include <linux/module.h> 10 #include <linux/kernel.h> 11 #include <linux/platform_device.h> 12 #include <linux/of.h> 13 #include <linux/of_platform.h> 14 #include <linux/suspend.h> 15 #include <linux/sys_soc.h> 16 #include <linux/usb/otg.h> 17 #include <linux/usb/of.h> 18 #include <linux/usb/role.h> 19 20 #include "core.h" 21 22 #define WRAP_CTR_REG 0x0 23 #define DISABLE_MULTI_REQ BIT(1) 24 #define DESC_R2W_MULTI_DISABLE BIT(9) 25 #define FORCE_PIPE3_PHY_STATUS_TO_0 BIT(13) 26 27 #define WRAP_USB2_PHY_UTMI_REG 0x8 28 #define TXHSVM_EN BIT(3) 29 30 #define WRAP_PHY_PIPE_REG 0xC 31 #define RESET_DISABLE_PIPE3_P0 BIT(0) 32 #define CLOCK_ENABLE_FOR_PIPE3_PCLK BIT(1) 33 34 #define WRAP_USB_HMAC_CTR0_REG 0x60 35 #define U3PORT_DIS BIT(8) 36 37 #define WRAP_USB2_PHY_REG 0x70 38 #define USB2_PHY_EN_PHY_PLL_PORT0 BIT(12) 39 #define USB2_PHY_EN_PHY_PLL_PORT1 BIT(13) 40 #define USB2_PHY_SWITCH_MASK 0x707 41 #define USB2_PHY_SWITCH_DEVICE 0x0 42 #define USB2_PHY_SWITCH_HOST 0x606 43 44 #define WRAP_APHY_REG 0x128 45 #define USB3_MBIAS_ENABLE BIT(1) 46 47 /* pm control */ 48 #define WRAP_USB_DBUS_PWR_CTRL_REG 0x160 49 #define USB_DBUS_PWR_CTRL_REG 0x0 50 #define DBUS_PWR_CTRL_EN BIT(0) 51 52 struct dwc3_rtk { 53 struct device *dev; 54 void __iomem *regs; 55 size_t regs_size; 56 void __iomem *pm_base; 57 58 struct dwc3 *dwc; 59 60 enum usb_role cur_role; 61 struct usb_role_switch *role_switch; 62 }; 63 64 static void switch_usb2_role(struct dwc3_rtk *rtk, enum usb_role role) 65 { 66 void __iomem *reg; 67 int val; 68 69 reg = rtk->regs + WRAP_USB2_PHY_REG; 70 val = ~USB2_PHY_SWITCH_MASK & readl(reg); 71 72 switch (role) { 73 case USB_ROLE_DEVICE: 74 writel(USB2_PHY_SWITCH_DEVICE | val, reg); 75 break; 76 case USB_ROLE_HOST: 77 writel(USB2_PHY_SWITCH_HOST | val, reg); 78 break; 79 default: 80 dev_dbg(rtk->dev, "%s: role=%d\n", __func__, role); 81 break; 82 } 83 } 84 85 static void switch_dwc3_role(struct dwc3_rtk *rtk, enum usb_role role) 86 { 87 if (!rtk->dwc->role_sw) 88 return; 89 90 usb_role_switch_set_role(rtk->dwc->role_sw, role); 91 } 92 93 static enum usb_role dwc3_rtk_get_role(struct dwc3_rtk *rtk) 94 { 95 enum usb_role role; 96 97 role = rtk->cur_role; 98 99 if (rtk->dwc && rtk->dwc->role_sw) 100 role = usb_role_switch_get_role(rtk->dwc->role_sw); 101 else 102 dev_dbg(rtk->dev, "%s not usb_role_switch role=%d\n", __func__, role); 103 104 return role; 105 } 106 107 static void dwc3_rtk_set_role(struct dwc3_rtk *rtk, enum usb_role role) 108 { 109 rtk->cur_role = role; 110 111 switch_dwc3_role(rtk, role); 112 mdelay(10); 113 switch_usb2_role(rtk, role); 114 } 115 116 #if IS_ENABLED(CONFIG_USB_ROLE_SWITCH) 117 static int dwc3_usb_role_switch_set(struct usb_role_switch *sw, enum usb_role role) 118 { 119 struct dwc3_rtk *rtk = usb_role_switch_get_drvdata(sw); 120 121 dwc3_rtk_set_role(rtk, role); 122 123 return 0; 124 } 125 126 static enum usb_role dwc3_usb_role_switch_get(struct usb_role_switch *sw) 127 { 128 struct dwc3_rtk *rtk = usb_role_switch_get_drvdata(sw); 129 130 return dwc3_rtk_get_role(rtk); 131 } 132 133 static int dwc3_rtk_setup_role_switch(struct dwc3_rtk *rtk) 134 { 135 struct usb_role_switch_desc dwc3_role_switch = {NULL}; 136 137 dwc3_role_switch.name = dev_name(rtk->dev); 138 dwc3_role_switch.driver_data = rtk; 139 dwc3_role_switch.allow_userspace_control = true; 140 dwc3_role_switch.fwnode = dev_fwnode(rtk->dev); 141 dwc3_role_switch.set = dwc3_usb_role_switch_set; 142 dwc3_role_switch.get = dwc3_usb_role_switch_get; 143 rtk->role_switch = usb_role_switch_register(rtk->dev, &dwc3_role_switch); 144 if (IS_ERR(rtk->role_switch)) 145 return PTR_ERR(rtk->role_switch); 146 147 return 0; 148 } 149 150 static int dwc3_rtk_remove_role_switch(struct dwc3_rtk *rtk) 151 { 152 if (rtk->role_switch) 153 usb_role_switch_unregister(rtk->role_switch); 154 155 rtk->role_switch = NULL; 156 157 return 0; 158 } 159 #else 160 #define dwc3_rtk_setup_role_switch(x) 0 161 #define dwc3_rtk_remove_role_switch(x) 0 162 #endif 163 164 static const char *const speed_names[] = { 165 [USB_SPEED_UNKNOWN] = "UNKNOWN", 166 [USB_SPEED_LOW] = "low-speed", 167 [USB_SPEED_FULL] = "full-speed", 168 [USB_SPEED_HIGH] = "high-speed", 169 [USB_SPEED_WIRELESS] = "wireless", 170 [USB_SPEED_SUPER] = "super-speed", 171 [USB_SPEED_SUPER_PLUS] = "super-speed-plus", 172 }; 173 174 static enum usb_device_speed __get_dwc3_maximum_speed(struct device_node *np) 175 { 176 struct device_node *dwc3_np; 177 const char *maximum_speed; 178 int ret; 179 180 dwc3_np = of_get_compatible_child(np, "snps,dwc3"); 181 if (!dwc3_np) 182 return USB_SPEED_UNKNOWN; 183 184 ret = of_property_read_string(dwc3_np, "maximum-speed", &maximum_speed); 185 if (ret < 0) 186 goto out; 187 188 ret = match_string(speed_names, ARRAY_SIZE(speed_names), maximum_speed); 189 190 out: 191 of_node_put(dwc3_np); 192 193 return (ret < 0) ? USB_SPEED_UNKNOWN : ret; 194 } 195 196 static int dwc3_rtk_init(struct dwc3_rtk *rtk) 197 { 198 struct device *dev = rtk->dev; 199 void __iomem *reg; 200 int val; 201 enum usb_device_speed maximum_speed; 202 const struct soc_device_attribute rtk_soc_kylin_a00[] = { 203 { .family = "Realtek Kylin", .revision = "A00", }, 204 { /* empty */ } }; 205 const struct soc_device_attribute rtk_soc_hercules[] = { 206 { .family = "Realtek Hercules", }, { /* empty */ } }; 207 const struct soc_device_attribute rtk_soc_thor[] = { 208 { .family = "Realtek Thor", }, { /* empty */ } }; 209 210 if (soc_device_match(rtk_soc_kylin_a00)) { 211 reg = rtk->regs + WRAP_CTR_REG; 212 val = readl(reg); 213 writel(DISABLE_MULTI_REQ | val, reg); 214 dev_info(dev, "[bug fixed] 1295/1296 A00: add workaround to disable multiple request for D-Bus"); 215 } 216 217 if (soc_device_match(rtk_soc_hercules)) { 218 reg = rtk->regs + WRAP_USB2_PHY_REG; 219 val = readl(reg); 220 writel(USB2_PHY_EN_PHY_PLL_PORT1 | val, reg); 221 dev_info(dev, "[bug fixed] 1395 add workaround to disable usb2 port 2 suspend!"); 222 } 223 224 reg = rtk->regs + WRAP_USB2_PHY_UTMI_REG; 225 val = readl(reg); 226 writel(TXHSVM_EN | val, reg); 227 228 maximum_speed = __get_dwc3_maximum_speed(dev->of_node); 229 if (maximum_speed != USB_SPEED_UNKNOWN && maximum_speed <= USB_SPEED_HIGH) { 230 if (soc_device_match(rtk_soc_thor)) { 231 reg = rtk->regs + WRAP_USB_HMAC_CTR0_REG; 232 val = readl(reg); 233 writel(U3PORT_DIS | val, reg); 234 } else { 235 reg = rtk->regs + WRAP_CTR_REG; 236 val = readl(reg); 237 writel(FORCE_PIPE3_PHY_STATUS_TO_0 | val, reg); 238 239 reg = rtk->regs + WRAP_PHY_PIPE_REG; 240 val = ~CLOCK_ENABLE_FOR_PIPE3_PCLK & readl(reg); 241 writel(RESET_DISABLE_PIPE3_P0 | val, reg); 242 243 reg = rtk->regs + WRAP_USB_HMAC_CTR0_REG; 244 val = readl(reg); 245 writel(U3PORT_DIS | val, reg); 246 247 reg = rtk->regs + WRAP_APHY_REG; 248 val = readl(reg); 249 writel(~USB3_MBIAS_ENABLE & val, reg); 250 251 dev_dbg(rtk->dev, "%s: disable usb 3.0 phy\n", __func__); 252 } 253 } 254 255 reg = rtk->regs + WRAP_CTR_REG; 256 val = readl(reg); 257 writel(DESC_R2W_MULTI_DISABLE | val, reg); 258 259 /* Set phy Dp/Dm initial state to host mode to avoid the Dp glitch */ 260 reg = rtk->regs + WRAP_USB2_PHY_REG; 261 val = ~USB2_PHY_SWITCH_MASK & readl(reg); 262 writel(USB2_PHY_SWITCH_HOST | val, reg); 263 264 if (rtk->pm_base) { 265 reg = rtk->pm_base + USB_DBUS_PWR_CTRL_REG; 266 val = DBUS_PWR_CTRL_EN | readl(reg); 267 writel(val, reg); 268 } 269 270 return 0; 271 } 272 273 static int dwc3_rtk_probe_dwc3_core(struct dwc3_rtk *rtk) 274 { 275 struct device *dev = rtk->dev; 276 struct device_node *node = dev->of_node; 277 struct platform_device *dwc3_pdev; 278 struct device *dwc3_dev; 279 struct device_node *dwc3_node; 280 enum usb_dr_mode dr_mode; 281 int ret = 0; 282 283 ret = dwc3_rtk_init(rtk); 284 if (ret) 285 return -EINVAL; 286 287 ret = of_platform_populate(node, NULL, NULL, dev); 288 if (ret) { 289 dev_err(dev, "failed to add dwc3 core\n"); 290 return ret; 291 } 292 293 dwc3_node = of_get_compatible_child(node, "snps,dwc3"); 294 if (!dwc3_node) { 295 dev_err(dev, "failed to find dwc3 core node\n"); 296 ret = -ENODEV; 297 goto depopulate; 298 } 299 300 dwc3_pdev = of_find_device_by_node(dwc3_node); 301 if (!dwc3_pdev) { 302 dev_err(dev, "failed to find dwc3 core platform_device\n"); 303 ret = -ENODEV; 304 goto err_node_put; 305 } 306 307 dwc3_dev = &dwc3_pdev->dev; 308 rtk->dwc = platform_get_drvdata(dwc3_pdev); 309 if (!rtk->dwc) { 310 dev_err(dev, "failed to find dwc3 core\n"); 311 ret = -ENODEV; 312 goto err_pdev_put; 313 } 314 315 dr_mode = usb_get_dr_mode(dwc3_dev); 316 if (dr_mode != rtk->dwc->dr_mode) { 317 dev_info(dev, "dts set dr_mode=%d, but dwc3 set dr_mode=%d\n", 318 dr_mode, rtk->dwc->dr_mode); 319 dr_mode = rtk->dwc->dr_mode; 320 } 321 322 switch (dr_mode) { 323 case USB_DR_MODE_PERIPHERAL: 324 rtk->cur_role = USB_ROLE_DEVICE; 325 break; 326 case USB_DR_MODE_HOST: 327 rtk->cur_role = USB_ROLE_HOST; 328 break; 329 default: 330 dev_dbg(rtk->dev, "%s: dr_mode=%d\n", __func__, dr_mode); 331 break; 332 } 333 334 if (device_property_read_bool(dwc3_dev, "usb-role-switch")) { 335 ret = dwc3_rtk_setup_role_switch(rtk); 336 if (ret) { 337 dev_err(dev, "dwc3_rtk_setup_role_switch fail=%d\n", ret); 338 goto err_pdev_put; 339 } 340 rtk->cur_role = dwc3_rtk_get_role(rtk); 341 } 342 343 switch_usb2_role(rtk, rtk->cur_role); 344 345 platform_device_put(dwc3_pdev); 346 of_node_put(dwc3_node); 347 348 return 0; 349 350 err_pdev_put: 351 platform_device_put(dwc3_pdev); 352 err_node_put: 353 of_node_put(dwc3_node); 354 depopulate: 355 of_platform_depopulate(dev); 356 357 return ret; 358 } 359 360 static int dwc3_rtk_probe(struct platform_device *pdev) 361 { 362 struct dwc3_rtk *rtk; 363 struct device *dev = &pdev->dev; 364 struct resource *res; 365 void __iomem *regs; 366 int ret = 0; 367 368 rtk = devm_kzalloc(dev, sizeof(*rtk), GFP_KERNEL); 369 if (!rtk) { 370 ret = -ENOMEM; 371 goto out; 372 } 373 374 platform_set_drvdata(pdev, rtk); 375 376 rtk->dev = dev; 377 378 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 379 if (!res) { 380 dev_err(dev, "missing memory resource\n"); 381 ret = -ENODEV; 382 goto out; 383 } 384 385 regs = devm_ioremap_resource(dev, res); 386 if (IS_ERR(regs)) { 387 ret = PTR_ERR(regs); 388 goto out; 389 } 390 391 rtk->regs = regs; 392 rtk->regs_size = resource_size(res); 393 394 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 395 if (res) { 396 rtk->pm_base = devm_ioremap_resource(dev, res); 397 if (IS_ERR(rtk->pm_base)) { 398 ret = PTR_ERR(rtk->pm_base); 399 goto out; 400 } 401 } 402 403 ret = dwc3_rtk_probe_dwc3_core(rtk); 404 405 out: 406 return ret; 407 } 408 409 static void dwc3_rtk_remove(struct platform_device *pdev) 410 { 411 struct dwc3_rtk *rtk = platform_get_drvdata(pdev); 412 413 rtk->dwc = NULL; 414 415 dwc3_rtk_remove_role_switch(rtk); 416 417 of_platform_depopulate(rtk->dev); 418 } 419 420 static void dwc3_rtk_shutdown(struct platform_device *pdev) 421 { 422 struct dwc3_rtk *rtk = platform_get_drvdata(pdev); 423 424 of_platform_depopulate(rtk->dev); 425 } 426 427 static const struct of_device_id rtk_dwc3_match[] = { 428 { .compatible = "realtek,rtd-dwc3" }, 429 {}, 430 }; 431 MODULE_DEVICE_TABLE(of, rtk_dwc3_match); 432 433 #ifdef CONFIG_PM_SLEEP 434 static int dwc3_rtk_suspend(struct device *dev) 435 { 436 return 0; 437 } 438 439 static int dwc3_rtk_resume(struct device *dev) 440 { 441 struct dwc3_rtk *rtk = dev_get_drvdata(dev); 442 443 dwc3_rtk_init(rtk); 444 445 switch_usb2_role(rtk, rtk->cur_role); 446 447 /* runtime set active to reflect active state. */ 448 pm_runtime_disable(dev); 449 pm_runtime_set_active(dev); 450 pm_runtime_enable(dev); 451 452 return 0; 453 } 454 455 static const struct dev_pm_ops dwc3_rtk_dev_pm_ops = { 456 SET_SYSTEM_SLEEP_PM_OPS(dwc3_rtk_suspend, dwc3_rtk_resume) 457 }; 458 459 #define DEV_PM_OPS (&dwc3_rtk_dev_pm_ops) 460 #else 461 #define DEV_PM_OPS NULL 462 #endif /* CONFIG_PM_SLEEP */ 463 464 static struct platform_driver dwc3_rtk_driver = { 465 .probe = dwc3_rtk_probe, 466 .remove_new = dwc3_rtk_remove, 467 .driver = { 468 .name = "rtk-dwc3", 469 .of_match_table = rtk_dwc3_match, 470 .pm = DEV_PM_OPS, 471 }, 472 .shutdown = dwc3_rtk_shutdown, 473 }; 474 475 module_platform_driver(dwc3_rtk_driver); 476 477 MODULE_AUTHOR("Stanley Chang <stanley_chang@realtek.com>"); 478 MODULE_DESCRIPTION("DesignWare USB3 Realtek Glue Layer"); 479 MODULE_ALIAS("platform:rtk-dwc3"); 480 MODULE_LICENSE("GPL"); 481 MODULE_SOFTDEP("pre: phy_rtk_usb2 phy_rtk_usb3"); 482