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