| .. | .. |
|---|
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
|---|
| 2 | | -/** |
|---|
| 2 | +/* |
|---|
| 3 | 3 | * core.c - DesignWare USB3 DRD Controller Core file |
|---|
| 4 | 4 | * |
|---|
| 5 | | - * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com |
|---|
| 5 | + * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com |
|---|
| 6 | 6 | * |
|---|
| 7 | 7 | * Authors: Felipe Balbi <balbi@ti.com>, |
|---|
| 8 | 8 | * Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
|---|
| 9 | 9 | */ |
|---|
| 10 | 10 | |
|---|
| 11 | | -#include <linux/async.h> |
|---|
| 12 | 11 | #include <linux/clk.h> |
|---|
| 13 | 12 | #include <linux/version.h> |
|---|
| 14 | 13 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 86 | 85 | * specified or set to OTG, then set the mode to peripheral. |
|---|
| 87 | 86 | */ |
|---|
| 88 | 87 | if (mode == USB_DR_MODE_OTG && |
|---|
| 89 | | - dwc->revision >= DWC3_REVISION_330A) |
|---|
| 88 | + (!IS_ENABLED(CONFIG_USB_ROLE_SWITCH) || |
|---|
| 89 | + !device_property_read_bool(dwc->dev, "usb-role-switch")) && |
|---|
| 90 | + !DWC3_VER_IS_PRIOR(DWC3, 330A)) |
|---|
| 90 | 91 | mode = USB_DR_MODE_PERIPHERAL; |
|---|
| 91 | 92 | } |
|---|
| 92 | 93 | |
|---|
| .. | .. |
|---|
| 118 | 119 | struct dwc3 *dwc = work_to_dwc(work); |
|---|
| 119 | 120 | unsigned long flags; |
|---|
| 120 | 121 | int ret; |
|---|
| 122 | + int retries = 1000; |
|---|
| 123 | + u32 reg; |
|---|
| 124 | + u32 desired_dr_role; |
|---|
| 121 | 125 | |
|---|
| 122 | | - if (dwc->dr_mode != USB_DR_MODE_OTG) |
|---|
| 123 | | - return; |
|---|
| 126 | + mutex_lock(&dwc->mutex); |
|---|
| 127 | + spin_lock_irqsave(&dwc->lock, flags); |
|---|
| 128 | + desired_dr_role = dwc->desired_dr_role; |
|---|
| 129 | + spin_unlock_irqrestore(&dwc->lock, flags); |
|---|
| 130 | + |
|---|
| 131 | + pm_runtime_get_sync(dwc->dev); |
|---|
| 132 | + |
|---|
| 133 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
|---|
| 134 | + if (dwc->desired_role_sw_mode == USB_DR_MODE_PERIPHERAL && |
|---|
| 135 | + dwc->desired_role_sw_mode != dwc->current_role_sw_mode) |
|---|
| 136 | + pm_runtime_get(dwc->dev); |
|---|
| 137 | + else if ((dwc->desired_role_sw_mode == USB_DR_MODE_UNKNOWN || |
|---|
| 138 | + dwc->desired_role_sw_mode == USB_DR_MODE_HOST) && |
|---|
| 139 | + dwc->current_role_sw_mode == USB_DR_MODE_PERIPHERAL) |
|---|
| 140 | + pm_runtime_put(dwc->dev); |
|---|
| 141 | + |
|---|
| 142 | + dwc->current_role_sw_mode = dwc->desired_role_sw_mode; |
|---|
| 143 | +#endif |
|---|
| 124 | 144 | |
|---|
| 125 | 145 | if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG) |
|---|
| 126 | 146 | dwc3_otg_update(dwc, 0); |
|---|
| 127 | 147 | |
|---|
| 128 | | - if (!dwc->desired_dr_role) |
|---|
| 129 | | - return; |
|---|
| 148 | + if (!desired_dr_role) |
|---|
| 149 | + goto out; |
|---|
| 130 | 150 | |
|---|
| 131 | | - if (dwc->en_runtime) |
|---|
| 132 | | - goto runtime; |
|---|
| 151 | + if (desired_dr_role == dwc->current_dr_role) |
|---|
| 152 | + goto out; |
|---|
| 133 | 153 | |
|---|
| 134 | | - if (dwc->desired_dr_role == dwc->current_dr_role) |
|---|
| 135 | | - return; |
|---|
| 136 | | - |
|---|
| 137 | | - if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev) |
|---|
| 138 | | - return; |
|---|
| 154 | + if (desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev) |
|---|
| 155 | + goto out; |
|---|
| 139 | 156 | |
|---|
| 140 | 157 | switch (dwc->current_dr_role) { |
|---|
| 141 | 158 | case DWC3_GCTL_PRTCAP_HOST: |
|---|
| .. | .. |
|---|
| 156 | 173 | break; |
|---|
| 157 | 174 | } |
|---|
| 158 | 175 | |
|---|
| 176 | + /* |
|---|
| 177 | + * When current_dr_role is not set, there's no role switching. |
|---|
| 178 | + * Only perform GCTL.CoreSoftReset when there's DRD role switching. |
|---|
| 179 | + */ |
|---|
| 180 | + if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) || |
|---|
| 181 | + DWC3_VER_IS_PRIOR(DWC31, 190A)) && |
|---|
| 182 | + desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) { |
|---|
| 183 | + reg = dwc3_readl(dwc->regs, DWC3_GCTL); |
|---|
| 184 | + reg |= DWC3_GCTL_CORESOFTRESET; |
|---|
| 185 | + dwc3_writel(dwc->regs, DWC3_GCTL, reg); |
|---|
| 186 | + |
|---|
| 187 | + /* |
|---|
| 188 | + * Wait for internal clocks to synchronized. DWC_usb31 and |
|---|
| 189 | + * DWC_usb32 may need at least 50ms (less for DWC_usb3). To |
|---|
| 190 | + * keep it consistent across different IPs, let's wait up to |
|---|
| 191 | + * 100ms before clearing GCTL.CORESOFTRESET. |
|---|
| 192 | + */ |
|---|
| 193 | + msleep(100); |
|---|
| 194 | + |
|---|
| 195 | + reg = dwc3_readl(dwc->regs, DWC3_GCTL); |
|---|
| 196 | + reg &= ~DWC3_GCTL_CORESOFTRESET; |
|---|
| 197 | + dwc3_writel(dwc->regs, DWC3_GCTL, reg); |
|---|
| 198 | + } |
|---|
| 199 | + |
|---|
| 159 | 200 | spin_lock_irqsave(&dwc->lock, flags); |
|---|
| 160 | 201 | |
|---|
| 161 | | - dwc3_set_prtcap(dwc, dwc->desired_dr_role); |
|---|
| 202 | + dwc3_set_prtcap(dwc, desired_dr_role); |
|---|
| 162 | 203 | |
|---|
| 163 | 204 | spin_unlock_irqrestore(&dwc->lock, flags); |
|---|
| 164 | 205 | |
|---|
| 165 | | - switch (dwc->desired_dr_role) { |
|---|
| 206 | + switch (desired_dr_role) { |
|---|
| 166 | 207 | case DWC3_GCTL_PRTCAP_HOST: |
|---|
| 167 | 208 | ret = dwc3_host_init(dwc); |
|---|
| 168 | 209 | if (ret) { |
|---|
| .. | .. |
|---|
| 172 | 213 | otg_set_vbus(dwc->usb2_phy->otg, true); |
|---|
| 173 | 214 | phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST); |
|---|
| 174 | 215 | phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST); |
|---|
| 175 | | - if (!of_device_is_compatible(dwc->dev->parent->of_node, |
|---|
| 176 | | - "rockchip,rk3399-dwc3")) |
|---|
| 177 | | - phy_calibrate(dwc->usb2_generic_phy); |
|---|
| 216 | + if (dwc->dis_split_quirk) { |
|---|
| 217 | + reg = dwc3_readl(dwc->regs, DWC3_GUCTL3); |
|---|
| 218 | + reg |= DWC3_GUCTL3_SPLITDISABLE; |
|---|
| 219 | + dwc3_writel(dwc->regs, DWC3_GUCTL3, reg); |
|---|
| 220 | + } |
|---|
| 178 | 221 | } |
|---|
| 179 | 222 | break; |
|---|
| 180 | 223 | case DWC3_GCTL_PRTCAP_DEVICE: |
|---|
| 224 | + reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
|---|
| 225 | + reg |= DWC3_DCTL_CSFTRST; |
|---|
| 226 | + dwc3_writel(dwc->regs, DWC3_DCTL, reg); |
|---|
| 227 | + |
|---|
| 228 | + if (DWC3_VER_IS_WITHIN(DWC31, 190A, ANY) || DWC3_IP_IS(DWC32)) |
|---|
| 229 | + retries = 10; |
|---|
| 230 | + |
|---|
| 231 | + do { |
|---|
| 232 | + reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
|---|
| 233 | + if (!(reg & DWC3_DCTL_CSFTRST)) |
|---|
| 234 | + goto done; |
|---|
| 235 | + |
|---|
| 236 | + if (DWC3_VER_IS_WITHIN(DWC31, 190A, ANY) || DWC3_IP_IS(DWC32)) |
|---|
| 237 | + msleep(20); |
|---|
| 238 | + else |
|---|
| 239 | + udelay(1); |
|---|
| 240 | + } while (--retries); |
|---|
| 241 | +done: |
|---|
| 242 | + if (DWC3_VER_IS_WITHIN(DWC31, ANY, 180A)) |
|---|
| 243 | + msleep(50); |
|---|
| 244 | + |
|---|
| 181 | 245 | dwc3_event_buffers_setup(dwc); |
|---|
| 182 | 246 | |
|---|
| 183 | 247 | if (dwc->usb2_phy) |
|---|
| .. | .. |
|---|
| 197 | 261 | break; |
|---|
| 198 | 262 | } |
|---|
| 199 | 263 | |
|---|
| 200 | | - return; |
|---|
| 201 | | - |
|---|
| 202 | | -runtime: |
|---|
| 203 | | - if (extcon_get_state(dwc->edev, EXTCON_USB) || |
|---|
| 204 | | - extcon_get_state(dwc->edev, EXTCON_USB_HOST)) { |
|---|
| 205 | | - if (dwc->drd_connected) { |
|---|
| 206 | | - /* |
|---|
| 207 | | - * If the connected flag is true, and the DWC3 is |
|---|
| 208 | | - * in device mode, it means that the Type-C cable |
|---|
| 209 | | - * is doing data role swap (UFP -> DFP), so we need |
|---|
| 210 | | - * to disconnect UFP first, and then switch DWC3 to |
|---|
| 211 | | - * DFP depends on the next extcon notifier. |
|---|
| 212 | | - */ |
|---|
| 213 | | - if (extcon_get_state(dwc->edev, EXTCON_USB_HOST) && |
|---|
| 214 | | - dwc->current_dr_role == DWC3_GCTL_PRTCAP_DEVICE) |
|---|
| 215 | | - goto disconnect; |
|---|
| 216 | | - else |
|---|
| 217 | | - return; |
|---|
| 218 | | - } |
|---|
| 219 | | - |
|---|
| 220 | | - dwc->current_dr_role = dwc->desired_dr_role; |
|---|
| 221 | | - pm_runtime_get_sync(dwc->dev); |
|---|
| 222 | | - /* |
|---|
| 223 | | - * We should set drd_connected true after runtime_resume to |
|---|
| 224 | | - * enable reset deassert. |
|---|
| 225 | | - */ |
|---|
| 226 | | - dwc->drd_connected = true; |
|---|
| 227 | | - |
|---|
| 228 | | - spin_lock_irqsave(&dwc->lock, flags); |
|---|
| 229 | | - |
|---|
| 230 | | - dwc3_set_prtcap(dwc, dwc->desired_dr_role); |
|---|
| 231 | | - |
|---|
| 232 | | - spin_unlock_irqrestore(&dwc->lock, flags); |
|---|
| 233 | | - |
|---|
| 234 | | - switch (dwc->current_dr_role) { |
|---|
| 235 | | - case DWC3_GCTL_PRTCAP_HOST: |
|---|
| 236 | | - phy_power_on(dwc->usb3_generic_phy); |
|---|
| 237 | | - ret = dwc3_host_init(dwc); |
|---|
| 238 | | - if (ret) { |
|---|
| 239 | | - dev_err(dwc->dev, |
|---|
| 240 | | - "failed to initialize host\n"); |
|---|
| 241 | | - } else { |
|---|
| 242 | | - if (dwc->usb2_phy) |
|---|
| 243 | | - otg_set_vbus(dwc->usb2_phy->otg, true); |
|---|
| 244 | | - phy_set_mode(dwc->usb2_generic_phy, |
|---|
| 245 | | - PHY_MODE_USB_HOST); |
|---|
| 246 | | - phy_set_mode(dwc->usb3_generic_phy, |
|---|
| 247 | | - PHY_MODE_USB_HOST); |
|---|
| 248 | | - if (!of_device_is_compatible( |
|---|
| 249 | | - dwc->dev->parent->of_node, |
|---|
| 250 | | - "rockchip,rk3399-dwc3")) |
|---|
| 251 | | - phy_calibrate(dwc->usb2_generic_phy); |
|---|
| 252 | | - } |
|---|
| 253 | | - break; |
|---|
| 254 | | - case DWC3_GCTL_PRTCAP_DEVICE: |
|---|
| 255 | | - if (dwc->usb2_phy) |
|---|
| 256 | | - otg_set_vbus(dwc->usb2_phy->otg, false); |
|---|
| 257 | | - phy_set_mode(dwc->usb2_generic_phy, |
|---|
| 258 | | - PHY_MODE_USB_DEVICE); |
|---|
| 259 | | - phy_set_mode(dwc->usb3_generic_phy, |
|---|
| 260 | | - PHY_MODE_USB_DEVICE); |
|---|
| 261 | | - dwc->gadget.ops->udc_set_speed(&dwc->gadget, |
|---|
| 262 | | - dwc->maximum_speed); |
|---|
| 263 | | - break; |
|---|
| 264 | | - case DWC3_GCTL_PRTCAP_OTG: |
|---|
| 265 | | - break; |
|---|
| 266 | | - default: |
|---|
| 267 | | - break; |
|---|
| 268 | | - } |
|---|
| 269 | | - } else { |
|---|
| 270 | | -disconnect: |
|---|
| 271 | | - switch (dwc->current_dr_role) { |
|---|
| 272 | | - case DWC3_GCTL_PRTCAP_HOST: |
|---|
| 273 | | - if (dwc->drd_connected) { |
|---|
| 274 | | - /* |
|---|
| 275 | | - * Set device mode to disable otg-vbus supply |
|---|
| 276 | | - * and enable vbus detect for inno USB2PHY. |
|---|
| 277 | | - */ |
|---|
| 278 | | - phy_set_mode(dwc->usb2_generic_phy, |
|---|
| 279 | | - PHY_MODE_USB_DEVICE); |
|---|
| 280 | | - phy_set_mode(dwc->usb3_generic_phy, |
|---|
| 281 | | - PHY_MODE_USB_DEVICE); |
|---|
| 282 | | - phy_power_off(dwc->usb3_generic_phy); |
|---|
| 283 | | - dwc3_host_exit(dwc); |
|---|
| 284 | | - } |
|---|
| 285 | | - break; |
|---|
| 286 | | - case DWC3_GCTL_PRTCAP_DEVICE: |
|---|
| 287 | | - if (dwc->connected) { |
|---|
| 288 | | - ret = wait_for_completion_timeout(&dwc->discon_done, |
|---|
| 289 | | - msecs_to_jiffies(DWC3_DISCON_TIMEOUT)); |
|---|
| 290 | | - if (!ret) |
|---|
| 291 | | - dev_warn(dwc->dev, |
|---|
| 292 | | - "timed out waiting for disconnect\n"); |
|---|
| 293 | | - } |
|---|
| 294 | | - |
|---|
| 295 | | - break; |
|---|
| 296 | | - case DWC3_GCTL_PRTCAP_OTG: |
|---|
| 297 | | - break; |
|---|
| 298 | | - default: |
|---|
| 299 | | - dwc->current_dr_role = dwc->desired_dr_role; |
|---|
| 300 | | - return; |
|---|
| 301 | | - } |
|---|
| 302 | | - |
|---|
| 303 | | - /* |
|---|
| 304 | | - * We should set drd_connected to false before |
|---|
| 305 | | - * runtime_suspend to enable reset assert. |
|---|
| 306 | | - */ |
|---|
| 307 | | - if (dwc->drd_connected) { |
|---|
| 308 | | - dwc->drd_connected = false; |
|---|
| 309 | | - pm_runtime_put_sync_suspend(dwc->dev); |
|---|
| 310 | | - } |
|---|
| 311 | | - } |
|---|
| 264 | +out: |
|---|
| 265 | + pm_runtime_mark_last_busy(dwc->dev); |
|---|
| 266 | + pm_runtime_put_autosuspend(dwc->dev); |
|---|
| 267 | + mutex_unlock(&dwc->mutex); |
|---|
| 312 | 268 | } |
|---|
| 313 | 269 | |
|---|
| 314 | 270 | void dwc3_set_mode(struct dwc3 *dwc, u32 mode) |
|---|
| 315 | 271 | { |
|---|
| 316 | 272 | unsigned long flags; |
|---|
| 273 | + |
|---|
| 274 | + if (dwc->dr_mode != USB_DR_MODE_OTG) |
|---|
| 275 | + return; |
|---|
| 317 | 276 | |
|---|
| 318 | 277 | spin_lock_irqsave(&dwc->lock, flags); |
|---|
| 319 | 278 | dwc->desired_dr_role = mode; |
|---|
| .. | .. |
|---|
| 340 | 299 | * dwc3_core_soft_reset - Issues core soft reset and PHY reset |
|---|
| 341 | 300 | * @dwc: pointer to our context structure |
|---|
| 342 | 301 | */ |
|---|
| 343 | | -static int dwc3_core_soft_reset(struct dwc3 *dwc) |
|---|
| 302 | +int dwc3_core_soft_reset(struct dwc3 *dwc) |
|---|
| 344 | 303 | { |
|---|
| 345 | 304 | u32 reg; |
|---|
| 346 | 305 | int retries = 1000; |
|---|
| 347 | | - int ret; |
|---|
| 348 | | - |
|---|
| 349 | | - usb_phy_init(dwc->usb2_phy); |
|---|
| 350 | | - usb_phy_init(dwc->usb3_phy); |
|---|
| 351 | | - ret = phy_init(dwc->usb2_generic_phy); |
|---|
| 352 | | - if (ret < 0) |
|---|
| 353 | | - return ret; |
|---|
| 354 | | - |
|---|
| 355 | | - ret = phy_init(dwc->usb3_generic_phy); |
|---|
| 356 | | - if (ret < 0) { |
|---|
| 357 | | - phy_exit(dwc->usb2_generic_phy); |
|---|
| 358 | | - return ret; |
|---|
| 359 | | - } |
|---|
| 360 | 306 | |
|---|
| 361 | 307 | /* |
|---|
| 362 | 308 | * We're resetting only the device side because, if we're in host mode, |
|---|
| 363 | 309 | * XHCI driver will reset the host block. If dwc3 was configured for |
|---|
| 364 | | - * host-only mode, then we can return early. |
|---|
| 310 | + * host-only mode or current role is host, then we can return early. |
|---|
| 365 | 311 | */ |
|---|
| 366 | | - if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) |
|---|
| 312 | + if (dwc->dr_mode == USB_DR_MODE_HOST || dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) |
|---|
| 367 | 313 | return 0; |
|---|
| 368 | 314 | |
|---|
| 369 | 315 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
|---|
| 370 | 316 | reg |= DWC3_DCTL_CSFTRST; |
|---|
| 371 | | - dwc3_writel(dwc->regs, DWC3_DCTL, reg); |
|---|
| 317 | + reg &= ~DWC3_DCTL_RUN_STOP; |
|---|
| 318 | + dwc3_gadget_dctl_write_safe(dwc, reg); |
|---|
| 319 | + |
|---|
| 320 | + /* |
|---|
| 321 | + * For DWC_usb31 controller 1.90a and later, the DCTL.CSFRST bit |
|---|
| 322 | + * is cleared only after all the clocks are synchronized. This can |
|---|
| 323 | + * take a little more than 50ms. Set the polling rate at 20ms |
|---|
| 324 | + * for 10 times instead. |
|---|
| 325 | + */ |
|---|
| 326 | + if (DWC3_VER_IS_WITHIN(DWC31, 190A, ANY) || DWC3_IP_IS(DWC32)) |
|---|
| 327 | + retries = 10; |
|---|
| 372 | 328 | |
|---|
| 373 | 329 | do { |
|---|
| 374 | 330 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
|---|
| 375 | 331 | if (!(reg & DWC3_DCTL_CSFTRST)) |
|---|
| 376 | 332 | goto done; |
|---|
| 377 | 333 | |
|---|
| 378 | | - udelay(1); |
|---|
| 334 | + if (DWC3_VER_IS_WITHIN(DWC31, 190A, ANY) || DWC3_IP_IS(DWC32)) |
|---|
| 335 | + msleep(20); |
|---|
| 336 | + else |
|---|
| 337 | + udelay(1); |
|---|
| 379 | 338 | } while (--retries); |
|---|
| 380 | 339 | |
|---|
| 381 | | - phy_exit(dwc->usb3_generic_phy); |
|---|
| 382 | | - phy_exit(dwc->usb2_generic_phy); |
|---|
| 383 | | - |
|---|
| 340 | + dev_warn(dwc->dev, "DWC3 controller soft reset failed.\n"); |
|---|
| 384 | 341 | return -ETIMEDOUT; |
|---|
| 385 | 342 | |
|---|
| 386 | 343 | done: |
|---|
| 387 | 344 | /* |
|---|
| 388 | | - * For DWC_usb31 controller, once DWC3_DCTL_CSFTRST bit is cleared, |
|---|
| 389 | | - * we must wait at least 50ms before accessing the PHY domain |
|---|
| 390 | | - * (synchronization delay). DWC_usb31 programming guide section 1.3.2. |
|---|
| 345 | + * For DWC_usb31 controller 1.80a and prior, once DCTL.CSFRST bit |
|---|
| 346 | + * is cleared, we must wait at least 50ms before accessing the PHY |
|---|
| 347 | + * domain (synchronization delay). |
|---|
| 391 | 348 | */ |
|---|
| 392 | | - if (dwc3_is_usb31(dwc)) |
|---|
| 349 | + if (DWC3_VER_IS_WITHIN(DWC31, ANY, 180A)) |
|---|
| 393 | 350 | msleep(50); |
|---|
| 394 | 351 | |
|---|
| 395 | 352 | return 0; |
|---|
| 396 | 353 | } |
|---|
| 397 | | - |
|---|
| 398 | | -static const struct clk_bulk_data dwc3_core_clks[] = { |
|---|
| 399 | | - { .id = "ref" }, |
|---|
| 400 | | - { .id = "bus_early" }, |
|---|
| 401 | | - { .id = "suspend" }, |
|---|
| 402 | | -}; |
|---|
| 403 | 354 | |
|---|
| 404 | 355 | /* |
|---|
| 405 | 356 | * dwc3_frame_length_adjustment - Adjusts frame length if required |
|---|
| .. | .. |
|---|
| 410 | 361 | u32 reg; |
|---|
| 411 | 362 | u32 dft; |
|---|
| 412 | 363 | |
|---|
| 413 | | - if (dwc->revision < DWC3_REVISION_250A) |
|---|
| 364 | + if (DWC3_VER_IS_PRIOR(DWC3, 250A)) |
|---|
| 414 | 365 | return; |
|---|
| 415 | 366 | |
|---|
| 416 | 367 | if (dwc->fladj == 0) |
|---|
| .. | .. |
|---|
| 445 | 396 | * otherwise ERR_PTR(errno). |
|---|
| 446 | 397 | */ |
|---|
| 447 | 398 | static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc, |
|---|
| 448 | | - unsigned length) |
|---|
| 399 | + unsigned int length) |
|---|
| 449 | 400 | { |
|---|
| 450 | 401 | struct dwc3_event_buffer *evt; |
|---|
| 451 | 402 | |
|---|
| .. | .. |
|---|
| 488 | 439 | * Returns 0 on success otherwise negative errno. In the error case, dwc |
|---|
| 489 | 440 | * may contain some buffers allocated but not all which were requested. |
|---|
| 490 | 441 | */ |
|---|
| 491 | | -static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length) |
|---|
| 442 | +static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned int length) |
|---|
| 492 | 443 | { |
|---|
| 493 | 444 | struct dwc3_event_buffer *evt; |
|---|
| 494 | 445 | |
|---|
| .. | .. |
|---|
| 644 | 595 | parms->hwparams6 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6); |
|---|
| 645 | 596 | parms->hwparams7 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS7); |
|---|
| 646 | 597 | parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8); |
|---|
| 598 | + |
|---|
| 599 | + if (DWC3_IP_IS(DWC32)) |
|---|
| 600 | + parms->hwparams9 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS9); |
|---|
| 647 | 601 | } |
|---|
| 648 | 602 | |
|---|
| 649 | 603 | static int dwc3_core_ulpi_init(struct dwc3 *dwc) |
|---|
| .. | .. |
|---|
| 672 | 626 | */ |
|---|
| 673 | 627 | static int dwc3_phy_setup(struct dwc3 *dwc) |
|---|
| 674 | 628 | { |
|---|
| 629 | + unsigned int hw_mode; |
|---|
| 675 | 630 | u32 reg; |
|---|
| 631 | + |
|---|
| 632 | + hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); |
|---|
| 676 | 633 | |
|---|
| 677 | 634 | reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); |
|---|
| 678 | 635 | |
|---|
| .. | .. |
|---|
| 688 | 645 | * will be '0' when the core is reset. Application needs to set it |
|---|
| 689 | 646 | * to '1' after the core initialization is completed. |
|---|
| 690 | 647 | */ |
|---|
| 691 | | - if (dwc->revision > DWC3_REVISION_194A) |
|---|
| 648 | + if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) |
|---|
| 692 | 649 | reg |= DWC3_GUSB3PIPECTL_SUSPHY; |
|---|
| 650 | + |
|---|
| 651 | + /* |
|---|
| 652 | + * For DRD controllers, GUSB3PIPECTL.SUSPENDENABLE must be cleared after |
|---|
| 653 | + * power-on reset, and it can be set after core initialization, which is |
|---|
| 654 | + * after device soft-reset during initialization. |
|---|
| 655 | + */ |
|---|
| 656 | + if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD) |
|---|
| 657 | + reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; |
|---|
| 693 | 658 | |
|---|
| 694 | 659 | if (dwc->u2ss_inp3_quirk) |
|---|
| 695 | 660 | reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK; |
|---|
| .. | .. |
|---|
| 741 | 706 | if (!(reg & DWC3_GUSB2PHYCFG_ULPI_UTMI)) |
|---|
| 742 | 707 | break; |
|---|
| 743 | 708 | } |
|---|
| 744 | | - /* FALLTHROUGH */ |
|---|
| 709 | + fallthrough; |
|---|
| 745 | 710 | case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI: |
|---|
| 746 | | - /* FALLTHROUGH */ |
|---|
| 747 | 711 | default: |
|---|
| 748 | 712 | break; |
|---|
| 749 | 713 | } |
|---|
| .. | .. |
|---|
| 771 | 735 | * be '0' when the core is reset. Application needs to set it to |
|---|
| 772 | 736 | * '1' after the core initialization is completed. |
|---|
| 773 | 737 | */ |
|---|
| 774 | | - if (dwc->revision > DWC3_REVISION_194A) |
|---|
| 738 | + if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) |
|---|
| 775 | 739 | reg |= DWC3_GUSB2PHYCFG_SUSPHY; |
|---|
| 740 | + |
|---|
| 741 | + /* |
|---|
| 742 | + * For DRD controllers, GUSB2PHYCFG.SUSPHY must be cleared after |
|---|
| 743 | + * power-on reset, and it can be set after core initialization, which is |
|---|
| 744 | + * after device soft-reset during initialization. |
|---|
| 745 | + */ |
|---|
| 746 | + if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD) |
|---|
| 747 | + reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; |
|---|
| 776 | 748 | |
|---|
| 777 | 749 | if (dwc->dis_u2_susphy_quirk) |
|---|
| 778 | 750 | reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; |
|---|
| .. | .. |
|---|
| 794 | 766 | { |
|---|
| 795 | 767 | dwc3_event_buffers_cleanup(dwc); |
|---|
| 796 | 768 | |
|---|
| 769 | + usb_phy_set_suspend(dwc->usb2_phy, 1); |
|---|
| 770 | + usb_phy_set_suspend(dwc->usb3_phy, 1); |
|---|
| 771 | + phy_power_off(dwc->usb2_generic_phy); |
|---|
| 772 | + phy_power_off(dwc->usb3_generic_phy); |
|---|
| 773 | + |
|---|
| 797 | 774 | usb_phy_shutdown(dwc->usb2_phy); |
|---|
| 798 | 775 | usb_phy_shutdown(dwc->usb3_phy); |
|---|
| 799 | 776 | phy_exit(dwc->usb2_generic_phy); |
|---|
| 800 | 777 | phy_exit(dwc->usb3_generic_phy); |
|---|
| 801 | 778 | |
|---|
| 802 | | - usb_phy_set_suspend(dwc->usb2_phy, 1); |
|---|
| 803 | | - usb_phy_set_suspend(dwc->usb3_phy, 1); |
|---|
| 804 | | - phy_power_off(dwc->usb2_generic_phy); |
|---|
| 805 | | - phy_power_off(dwc->usb3_generic_phy); |
|---|
| 806 | | - clk_bulk_disable(dwc->num_clks, dwc->clks); |
|---|
| 807 | | - clk_bulk_unprepare(dwc->num_clks, dwc->clks); |
|---|
| 808 | | - |
|---|
| 809 | | - if (!dwc->drd_connected && dwc->dr_mode == USB_DR_MODE_OTG) |
|---|
| 810 | | - reset_control_assert(dwc->reset); |
|---|
| 779 | + clk_bulk_disable_unprepare(dwc->num_clks, dwc->clks); |
|---|
| 780 | + reset_control_assert(dwc->reset); |
|---|
| 811 | 781 | } |
|---|
| 812 | 782 | |
|---|
| 813 | 783 | static bool dwc3_core_is_valid(struct dwc3 *dwc) |
|---|
| .. | .. |
|---|
| 815 | 785 | u32 reg; |
|---|
| 816 | 786 | |
|---|
| 817 | 787 | reg = dwc3_readl(dwc->regs, DWC3_GSNPSID); |
|---|
| 788 | + dwc->ip = DWC3_GSNPS_ID(reg); |
|---|
| 818 | 789 | |
|---|
| 819 | 790 | /* This should read as U3 followed by revision number */ |
|---|
| 820 | | - if ((reg & DWC3_GSNPSID_MASK) == 0x55330000) { |
|---|
| 821 | | - /* Detected DWC_usb3 IP */ |
|---|
| 791 | + if (DWC3_IP_IS(DWC3)) { |
|---|
| 822 | 792 | dwc->revision = reg; |
|---|
| 823 | | - } else if ((reg & DWC3_GSNPSID_MASK) == 0x33310000) { |
|---|
| 824 | | - /* Detected DWC_usb31 IP */ |
|---|
| 793 | + } else if (DWC3_IP_IS(DWC31) || DWC3_IP_IS(DWC32)) { |
|---|
| 825 | 794 | dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER); |
|---|
| 826 | | - dwc->revision |= DWC3_REVISION_IS_DWC31; |
|---|
| 827 | 795 | dwc->version_type = dwc3_readl(dwc->regs, DWC3_VER_TYPE); |
|---|
| 828 | 796 | } else { |
|---|
| 829 | 797 | return false; |
|---|
| .. | .. |
|---|
| 856 | 824 | */ |
|---|
| 857 | 825 | if ((dwc->dr_mode == USB_DR_MODE_HOST || |
|---|
| 858 | 826 | dwc->dr_mode == USB_DR_MODE_OTG) && |
|---|
| 859 | | - (dwc->revision >= DWC3_REVISION_210A && |
|---|
| 860 | | - dwc->revision <= DWC3_REVISION_250A)) |
|---|
| 827 | + DWC3_VER_IS_WITHIN(DWC3, 210A, 250A)) |
|---|
| 861 | 828 | reg |= DWC3_GCTL_DSBLCLKGTNG | DWC3_GCTL_SOFITPSYNC; |
|---|
| 862 | 829 | else |
|---|
| 863 | 830 | reg &= ~DWC3_GCTL_DSBLCLKGTNG; |
|---|
| .. | .. |
|---|
| 879 | 846 | |
|---|
| 880 | 847 | /* check if current dwc3 is on simulation board */ |
|---|
| 881 | 848 | if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) { |
|---|
| 882 | | - dev_info(dwc->dev, "Running with FPGA optmizations\n"); |
|---|
| 849 | + dev_info(dwc->dev, "Running with FPGA optimizations\n"); |
|---|
| 883 | 850 | dwc->is_fpga = true; |
|---|
| 884 | 851 | } |
|---|
| 885 | 852 | |
|---|
| .. | .. |
|---|
| 900 | 867 | * and falls back to high-speed mode which causes |
|---|
| 901 | 868 | * the device to enter a Connect/Disconnect loop |
|---|
| 902 | 869 | */ |
|---|
| 903 | | - if (dwc->revision < DWC3_REVISION_190A) |
|---|
| 870 | + if (DWC3_VER_IS_PRIOR(DWC3, 190A)) |
|---|
| 904 | 871 | reg |= DWC3_GCTL_U2RSTECN; |
|---|
| 905 | 872 | |
|---|
| 906 | 873 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); |
|---|
| .. | .. |
|---|
| 932 | 899 | * result = 1, means INCRx burst mode supported. |
|---|
| 933 | 900 | * result > 1, means undefined length burst mode supported. |
|---|
| 934 | 901 | */ |
|---|
| 935 | | - ntype = device_property_read_u32_array(dev, |
|---|
| 936 | | - "snps,incr-burst-type-adjustment", NULL, 0); |
|---|
| 902 | + ntype = device_property_count_u32(dev, "snps,incr-burst-type-adjustment"); |
|---|
| 937 | 903 | if (ntype <= 0) |
|---|
| 938 | 904 | return; |
|---|
| 939 | 905 | |
|---|
| .. | .. |
|---|
| 1012 | 978 | */ |
|---|
| 1013 | 979 | static int dwc3_core_init(struct dwc3 *dwc) |
|---|
| 1014 | 980 | { |
|---|
| 981 | + unsigned int hw_mode; |
|---|
| 1015 | 982 | u32 reg; |
|---|
| 1016 | 983 | int ret; |
|---|
| 984 | + |
|---|
| 985 | + hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); |
|---|
| 1017 | 986 | |
|---|
| 1018 | 987 | /* |
|---|
| 1019 | 988 | * Write Linux Version Code to our GUID register so it's easy to figure |
|---|
| .. | .. |
|---|
| 1021 | 990 | */ |
|---|
| 1022 | 991 | dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE); |
|---|
| 1023 | 992 | |
|---|
| 1024 | | - /* Handle USB2.0-only core configuration */ |
|---|
| 1025 | | - if (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) == |
|---|
| 1026 | | - DWC3_GHWPARAMS3_SSPHY_IFC_DIS) { |
|---|
| 1027 | | - if (dwc->maximum_speed == USB_SPEED_SUPER) |
|---|
| 1028 | | - dwc->maximum_speed = USB_SPEED_HIGH; |
|---|
| 1029 | | - } |
|---|
| 1030 | | - |
|---|
| 1031 | 993 | ret = dwc3_phy_setup(dwc); |
|---|
| 1032 | 994 | if (ret) |
|---|
| 1033 | 995 | goto err0; |
|---|
| 1034 | 996 | |
|---|
| 1035 | 997 | if (!dwc->ulpi_ready) { |
|---|
| 1036 | 998 | ret = dwc3_core_ulpi_init(dwc); |
|---|
| 1037 | | - if (ret) |
|---|
| 999 | + if (ret) { |
|---|
| 1000 | + if (ret == -ETIMEDOUT) { |
|---|
| 1001 | + dwc3_core_soft_reset(dwc); |
|---|
| 1002 | + ret = -EPROBE_DEFER; |
|---|
| 1003 | + } |
|---|
| 1038 | 1004 | goto err0; |
|---|
| 1005 | + } |
|---|
| 1039 | 1006 | dwc->ulpi_ready = true; |
|---|
| 1040 | 1007 | } |
|---|
| 1041 | 1008 | |
|---|
| .. | .. |
|---|
| 1046 | 1013 | dwc->phys_ready = true; |
|---|
| 1047 | 1014 | } |
|---|
| 1048 | 1015 | |
|---|
| 1016 | + usb_phy_init(dwc->usb2_phy); |
|---|
| 1017 | + usb_phy_init(dwc->usb3_phy); |
|---|
| 1018 | + ret = phy_init(dwc->usb2_generic_phy); |
|---|
| 1019 | + if (ret < 0) |
|---|
| 1020 | + goto err0a; |
|---|
| 1021 | + |
|---|
| 1022 | + ret = phy_init(dwc->usb3_generic_phy); |
|---|
| 1023 | + if (ret < 0) { |
|---|
| 1024 | + phy_exit(dwc->usb2_generic_phy); |
|---|
| 1025 | + goto err0a; |
|---|
| 1026 | + } |
|---|
| 1027 | + |
|---|
| 1049 | 1028 | ret = dwc3_core_soft_reset(dwc); |
|---|
| 1050 | 1029 | if (ret) |
|---|
| 1051 | | - goto err0a; |
|---|
| 1030 | + goto err1; |
|---|
| 1031 | + |
|---|
| 1032 | + if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD && |
|---|
| 1033 | + !DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) { |
|---|
| 1034 | + if (!dwc->dis_u3_susphy_quirk) { |
|---|
| 1035 | + reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); |
|---|
| 1036 | + reg |= DWC3_GUSB3PIPECTL_SUSPHY; |
|---|
| 1037 | + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); |
|---|
| 1038 | + } |
|---|
| 1039 | + |
|---|
| 1040 | + if (!dwc->dis_u2_susphy_quirk) { |
|---|
| 1041 | + reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); |
|---|
| 1042 | + reg |= DWC3_GUSB2PHYCFG_SUSPHY; |
|---|
| 1043 | + dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); |
|---|
| 1044 | + } |
|---|
| 1045 | + } |
|---|
| 1052 | 1046 | |
|---|
| 1053 | 1047 | dwc3_core_setup_global_control(dwc); |
|---|
| 1054 | 1048 | dwc3_core_num_eps(dwc); |
|---|
| .. | .. |
|---|
| 1083 | 1077 | * the DWC_usb3 controller. It is NOT available in the |
|---|
| 1084 | 1078 | * DWC_usb31 controller. |
|---|
| 1085 | 1079 | */ |
|---|
| 1086 | | - if (!dwc3_is_usb31(dwc) && dwc->revision >= DWC3_REVISION_310A) { |
|---|
| 1080 | + if (DWC3_VER_IS_WITHIN(DWC3, 310A, ANY)) { |
|---|
| 1087 | 1081 | reg = dwc3_readl(dwc->regs, DWC3_GUCTL2); |
|---|
| 1088 | 1082 | reg |= DWC3_GUCTL2_RST_ACTBITLATER; |
|---|
| 1089 | 1083 | dwc3_writel(dwc->regs, DWC3_GUCTL2, reg); |
|---|
| 1090 | 1084 | } |
|---|
| 1091 | 1085 | |
|---|
| 1092 | | - if (dwc->revision >= DWC3_REVISION_250A) { |
|---|
| 1086 | + if (!DWC3_VER_IS_PRIOR(DWC3, 250A)) { |
|---|
| 1093 | 1087 | reg = dwc3_readl(dwc->regs, DWC3_GUCTL1); |
|---|
| 1094 | 1088 | |
|---|
| 1095 | 1089 | /* |
|---|
| 1096 | 1090 | * Enable hardware control of sending remote wakeup |
|---|
| 1097 | 1091 | * in HS when the device is in the L1 state. |
|---|
| 1098 | 1092 | */ |
|---|
| 1099 | | - if (dwc->revision >= DWC3_REVISION_290A) |
|---|
| 1093 | + if (!DWC3_VER_IS_PRIOR(DWC3, 290A)) |
|---|
| 1100 | 1094 | reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW; |
|---|
| 1095 | + |
|---|
| 1096 | + /* |
|---|
| 1097 | + * Decouple USB 2.0 L1 & L2 events which will allow for |
|---|
| 1098 | + * gadget driver to only receive U3/L2 suspend & wakeup |
|---|
| 1099 | + * events and prevent the more frequent L1 LPM transitions |
|---|
| 1100 | + * from interrupting the driver. |
|---|
| 1101 | + */ |
|---|
| 1102 | + if (!DWC3_VER_IS_PRIOR(DWC3, 300A)) |
|---|
| 1103 | + reg |= DWC3_GUCTL1_DEV_DECOUPLE_L1L2_EVT; |
|---|
| 1101 | 1104 | |
|---|
| 1102 | 1105 | if (dwc->dis_tx_ipgap_linecheck_quirk) |
|---|
| 1103 | 1106 | reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS; |
|---|
| .. | .. |
|---|
| 1105 | 1108 | if (dwc->parkmode_disable_ss_quirk) |
|---|
| 1106 | 1109 | reg |= DWC3_GUCTL1_PARKMODE_DISABLE_SS; |
|---|
| 1107 | 1110 | |
|---|
| 1108 | | - if (dwc->maximum_speed == USB_SPEED_HIGH || |
|---|
| 1109 | | - dwc->maximum_speed == USB_SPEED_FULL) |
|---|
| 1111 | +#ifdef CONFIG_NO_GKI |
|---|
| 1112 | + if (dwc->parkmode_disable_hs_quirk) |
|---|
| 1113 | + reg |= DWC3_GUCTL1_PARKMODE_DISABLE_HS; |
|---|
| 1114 | +#endif |
|---|
| 1115 | + |
|---|
| 1116 | + if (DWC3_VER_IS_WITHIN(DWC3, 290A, ANY) && |
|---|
| 1117 | + (dwc->maximum_speed == USB_SPEED_HIGH || |
|---|
| 1118 | + dwc->maximum_speed == USB_SPEED_FULL)) |
|---|
| 1110 | 1119 | reg |= DWC3_GUCTL1_DEV_FORCE_20_CLK_FOR_30_CLK; |
|---|
| 1111 | 1120 | |
|---|
| 1112 | 1121 | dwc3_writel(dwc->regs, DWC3_GUCTL1, reg); |
|---|
| 1113 | | - } |
|---|
| 1114 | | - |
|---|
| 1115 | | - if (dwc->dr_mode == USB_DR_MODE_HOST || |
|---|
| 1116 | | - dwc->dr_mode == USB_DR_MODE_OTG) { |
|---|
| 1117 | | - reg = dwc3_readl(dwc->regs, DWC3_GUCTL); |
|---|
| 1118 | | - |
|---|
| 1119 | | - /* |
|---|
| 1120 | | - * Enable Auto retry Feature to make the controller operating in |
|---|
| 1121 | | - * Host mode on seeing transaction errors(CRC errors or internal |
|---|
| 1122 | | - * overrun scenerios) on IN transfers to reply to the device |
|---|
| 1123 | | - * with a non-terminating retry ACK (i.e, an ACK transcation |
|---|
| 1124 | | - * packet with Retry=1 & Nump != 0) |
|---|
| 1125 | | - */ |
|---|
| 1126 | | - reg |= DWC3_GUCTL_HSTINAUTORETRY; |
|---|
| 1127 | | - |
|---|
| 1128 | | - dwc3_writel(dwc->regs, DWC3_GUCTL, reg); |
|---|
| 1129 | 1122 | } |
|---|
| 1130 | 1123 | |
|---|
| 1131 | 1124 | /* |
|---|
| 1132 | 1125 | * Must config both number of packets and max burst settings to enable |
|---|
| 1133 | 1126 | * RX and/or TX threshold. |
|---|
| 1134 | 1127 | */ |
|---|
| 1135 | | - if (dwc3_is_usb31(dwc) && dwc->dr_mode == USB_DR_MODE_HOST) { |
|---|
| 1128 | + if (!DWC3_IP_IS(DWC3) && dwc->dr_mode == USB_DR_MODE_HOST) { |
|---|
| 1136 | 1129 | u8 rx_thr_num = dwc->rx_thr_num_pkt_prd; |
|---|
| 1137 | 1130 | u8 rx_maxburst = dwc->rx_max_burst_prd; |
|---|
| 1138 | 1131 | u8 tx_thr_num = dwc->tx_thr_num_pkt_prd; |
|---|
| .. | .. |
|---|
| 1206 | 1199 | |
|---|
| 1207 | 1200 | if (IS_ERR(dwc->usb2_phy)) { |
|---|
| 1208 | 1201 | ret = PTR_ERR(dwc->usb2_phy); |
|---|
| 1209 | | - if (ret == -ENXIO || ret == -ENODEV) { |
|---|
| 1202 | + if (ret == -ENXIO || ret == -ENODEV) |
|---|
| 1210 | 1203 | dwc->usb2_phy = NULL; |
|---|
| 1211 | | - } else if (ret == -EPROBE_DEFER) { |
|---|
| 1212 | | - return ret; |
|---|
| 1213 | | - } else { |
|---|
| 1214 | | - dev_err(dev, "no usb2 phy configured\n"); |
|---|
| 1215 | | - return ret; |
|---|
| 1216 | | - } |
|---|
| 1204 | + else |
|---|
| 1205 | + return dev_err_probe(dev, ret, "no usb2 phy configured\n"); |
|---|
| 1217 | 1206 | } |
|---|
| 1218 | 1207 | |
|---|
| 1219 | 1208 | if (IS_ERR(dwc->usb3_phy)) { |
|---|
| 1220 | 1209 | ret = PTR_ERR(dwc->usb3_phy); |
|---|
| 1221 | | - if (ret == -ENXIO || ret == -ENODEV) { |
|---|
| 1210 | + if (ret == -ENXIO || ret == -ENODEV) |
|---|
| 1222 | 1211 | dwc->usb3_phy = NULL; |
|---|
| 1223 | | - } else if (ret == -EPROBE_DEFER) { |
|---|
| 1224 | | - return ret; |
|---|
| 1225 | | - } else { |
|---|
| 1226 | | - dev_err(dev, "no usb3 phy configured\n"); |
|---|
| 1227 | | - return ret; |
|---|
| 1228 | | - } |
|---|
| 1212 | + else |
|---|
| 1213 | + return dev_err_probe(dev, ret, "no usb3 phy configured\n"); |
|---|
| 1229 | 1214 | } |
|---|
| 1230 | 1215 | |
|---|
| 1231 | 1216 | dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy"); |
|---|
| 1232 | 1217 | if (IS_ERR(dwc->usb2_generic_phy)) { |
|---|
| 1233 | 1218 | ret = PTR_ERR(dwc->usb2_generic_phy); |
|---|
| 1234 | | - if (ret == -ENOSYS || ret == -ENODEV) { |
|---|
| 1219 | + if (ret == -ENOSYS || ret == -ENODEV) |
|---|
| 1235 | 1220 | dwc->usb2_generic_phy = NULL; |
|---|
| 1236 | | - } else if (ret == -EPROBE_DEFER) { |
|---|
| 1237 | | - return ret; |
|---|
| 1238 | | - } else { |
|---|
| 1239 | | - dev_err(dev, "no usb2 phy configured\n"); |
|---|
| 1240 | | - return ret; |
|---|
| 1241 | | - } |
|---|
| 1221 | + else |
|---|
| 1222 | + return dev_err_probe(dev, ret, "no usb2 phy configured\n"); |
|---|
| 1242 | 1223 | } |
|---|
| 1243 | 1224 | |
|---|
| 1244 | 1225 | dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy"); |
|---|
| 1245 | 1226 | if (IS_ERR(dwc->usb3_generic_phy)) { |
|---|
| 1246 | 1227 | ret = PTR_ERR(dwc->usb3_generic_phy); |
|---|
| 1247 | | - if (ret == -ENOSYS || ret == -ENODEV) { |
|---|
| 1228 | + if (ret == -ENOSYS || ret == -ENODEV) |
|---|
| 1248 | 1229 | dwc->usb3_generic_phy = NULL; |
|---|
| 1249 | | - } else if (ret == -EPROBE_DEFER) { |
|---|
| 1250 | | - return ret; |
|---|
| 1251 | | - } else { |
|---|
| 1252 | | - dev_err(dev, "no usb3 phy configured\n"); |
|---|
| 1253 | | - return ret; |
|---|
| 1254 | | - } |
|---|
| 1230 | + else |
|---|
| 1231 | + return dev_err_probe(dev, ret, "no usb3 phy configured\n"); |
|---|
| 1255 | 1232 | } |
|---|
| 1256 | 1233 | |
|---|
| 1257 | 1234 | return 0; |
|---|
| .. | .. |
|---|
| 1272 | 1249 | phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_DEVICE); |
|---|
| 1273 | 1250 | |
|---|
| 1274 | 1251 | ret = dwc3_gadget_init(dwc); |
|---|
| 1275 | | - if (ret) { |
|---|
| 1276 | | - if (ret != -EPROBE_DEFER) |
|---|
| 1277 | | - dev_err(dev, "failed to initialize gadget\n"); |
|---|
| 1278 | | - return ret; |
|---|
| 1279 | | - } |
|---|
| 1280 | | - |
|---|
| 1281 | | - if (dwc->uwk_en) |
|---|
| 1282 | | - device_init_wakeup(dev, true); |
|---|
| 1252 | + if (ret) |
|---|
| 1253 | + return dev_err_probe(dev, ret, "failed to initialize gadget\n"); |
|---|
| 1283 | 1254 | break; |
|---|
| 1284 | 1255 | case USB_DR_MODE_HOST: |
|---|
| 1285 | | - /* |
|---|
| 1286 | | - * To prevent usb device be reenumerated when resume from PM |
|---|
| 1287 | | - * suspend, we set the flag dwc->power.can_wakeup which can |
|---|
| 1288 | | - * keep PD on and run phy_power_on again to avoid |
|---|
| 1289 | | - * phy_power_on failed (error -110) in Rockchip platform. |
|---|
| 1290 | | - */ |
|---|
| 1291 | | - if (!of_machine_is_compatible("rockchip,rk3568") && |
|---|
| 1292 | | - !of_machine_is_compatible("rockchip,rk3566")) |
|---|
| 1293 | | - device_init_wakeup(dev, true); |
|---|
| 1294 | | - |
|---|
| 1295 | | - phy_power_on(dwc->usb3_generic_phy); |
|---|
| 1296 | | - |
|---|
| 1297 | 1256 | dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST); |
|---|
| 1298 | 1257 | |
|---|
| 1299 | 1258 | if (dwc->usb2_phy) |
|---|
| .. | .. |
|---|
| 1302 | 1261 | phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST); |
|---|
| 1303 | 1262 | |
|---|
| 1304 | 1263 | ret = dwc3_host_init(dwc); |
|---|
| 1305 | | - if (ret) { |
|---|
| 1306 | | - if (ret != -EPROBE_DEFER) |
|---|
| 1307 | | - dev_err(dev, "failed to initialize host\n"); |
|---|
| 1308 | | - return ret; |
|---|
| 1309 | | - } |
|---|
| 1310 | | - if (!of_device_is_compatible(dwc->dev->parent->of_node, |
|---|
| 1311 | | - "rockchip,rk3399-dwc3")) |
|---|
| 1312 | | - phy_calibrate(dwc->usb2_generic_phy); |
|---|
| 1264 | + if (ret) |
|---|
| 1265 | + return dev_err_probe(dev, ret, "failed to initialize host\n"); |
|---|
| 1313 | 1266 | break; |
|---|
| 1314 | 1267 | case USB_DR_MODE_OTG: |
|---|
| 1315 | 1268 | INIT_WORK(&dwc->drd_work, __dwc3_set_mode); |
|---|
| 1316 | | - if (dwc->en_runtime) { |
|---|
| 1317 | | - ret = dwc3_gadget_init(dwc); |
|---|
| 1318 | | - if (ret) { |
|---|
| 1319 | | - if (ret != -EPROBE_DEFER) |
|---|
| 1320 | | - dev_err(dev, "failed to initialize gadget\n"); |
|---|
| 1321 | | - return ret; |
|---|
| 1322 | | - } |
|---|
| 1323 | | - } |
|---|
| 1324 | 1269 | ret = dwc3_drd_init(dwc); |
|---|
| 1325 | | - if (ret) { |
|---|
| 1326 | | - if (dwc->en_runtime) |
|---|
| 1327 | | - dwc3_gadget_exit(dwc); |
|---|
| 1328 | | - |
|---|
| 1329 | | - if (ret != -EPROBE_DEFER) |
|---|
| 1330 | | - dev_err(dev, "failed to initialize dual-role\n"); |
|---|
| 1331 | | - return ret; |
|---|
| 1332 | | - } |
|---|
| 1333 | | - |
|---|
| 1334 | | - if (dwc->uwk_en) |
|---|
| 1335 | | - device_init_wakeup(dev, true); |
|---|
| 1270 | + if (ret) |
|---|
| 1271 | + return dev_err_probe(dev, ret, "failed to initialize dual-role\n"); |
|---|
| 1336 | 1272 | break; |
|---|
| 1337 | 1273 | default: |
|---|
| 1338 | 1274 | dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode); |
|---|
| .. | .. |
|---|
| 1369 | 1305 | u8 lpm_nyet_threshold; |
|---|
| 1370 | 1306 | u8 tx_de_emphasis; |
|---|
| 1371 | 1307 | u8 hird_threshold; |
|---|
| 1372 | | - u8 rx_thr_num_pkt_prd; |
|---|
| 1373 | | - u8 rx_max_burst_prd; |
|---|
| 1374 | | - u8 tx_thr_num_pkt_prd; |
|---|
| 1375 | | - u8 tx_max_burst_prd; |
|---|
| 1308 | + u8 rx_thr_num_pkt_prd = 0; |
|---|
| 1309 | + u8 rx_max_burst_prd = 0; |
|---|
| 1310 | + u8 tx_thr_num_pkt_prd = 0; |
|---|
| 1311 | + u8 tx_max_burst_prd = 0; |
|---|
| 1312 | + u8 tx_fifo_resize_max_num; |
|---|
| 1313 | + const char *usb_psy_name; |
|---|
| 1314 | + int ret; |
|---|
| 1376 | 1315 | |
|---|
| 1377 | 1316 | /* default to highest possible threshold */ |
|---|
| 1378 | 1317 | lpm_nyet_threshold = 0xf; |
|---|
| .. | .. |
|---|
| 1386 | 1325 | */ |
|---|
| 1387 | 1326 | hird_threshold = 12; |
|---|
| 1388 | 1327 | |
|---|
| 1328 | + /* |
|---|
| 1329 | + * default to a TXFIFO size large enough to fit 6 max packets. This |
|---|
| 1330 | + * allows for systems with larger bus latencies to have some headroom |
|---|
| 1331 | + * for endpoints that have a large bMaxBurst value. |
|---|
| 1332 | + */ |
|---|
| 1333 | + tx_fifo_resize_max_num = 6; |
|---|
| 1334 | + |
|---|
| 1389 | 1335 | dwc->maximum_speed = usb_get_maximum_speed(dev); |
|---|
| 1336 | + dwc->max_ssp_rate = usb_get_maximum_ssp_rate(dev); |
|---|
| 1390 | 1337 | dwc->dr_mode = usb_get_dr_mode(dev); |
|---|
| 1391 | 1338 | dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node); |
|---|
| 1392 | 1339 | |
|---|
| .. | .. |
|---|
| 1396 | 1343 | dwc->sysdev = dwc->dev->parent; |
|---|
| 1397 | 1344 | else |
|---|
| 1398 | 1345 | dwc->sysdev = dwc->dev; |
|---|
| 1346 | + |
|---|
| 1347 | + ret = device_property_read_string(dev, "usb-psy-name", &usb_psy_name); |
|---|
| 1348 | + if (ret >= 0) { |
|---|
| 1349 | + dwc->usb_psy = power_supply_get_by_name(usb_psy_name); |
|---|
| 1350 | + if (!dwc->usb_psy) |
|---|
| 1351 | + dev_err(dev, "couldn't get usb power supply\n"); |
|---|
| 1352 | + } |
|---|
| 1399 | 1353 | |
|---|
| 1400 | 1354 | dwc->has_lpm_erratum = device_property_read_bool(dev, |
|---|
| 1401 | 1355 | "snps,has-lpm-erratum"); |
|---|
| .. | .. |
|---|
| 1411 | 1365 | "snps,usb3_lpm_capable"); |
|---|
| 1412 | 1366 | dwc->usb2_lpm_disable = device_property_read_bool(dev, |
|---|
| 1413 | 1367 | "snps,usb2-lpm-disable"); |
|---|
| 1368 | + dwc->usb2_gadget_lpm_disable = device_property_read_bool(dev, |
|---|
| 1369 | + "snps,usb2-gadget-lpm-disable"); |
|---|
| 1414 | 1370 | device_property_read_u8(dev, "snps,rx-thr-num-pkt-prd", |
|---|
| 1415 | 1371 | &rx_thr_num_pkt_prd); |
|---|
| 1416 | 1372 | device_property_read_u8(dev, "snps,rx-max-burst-prd", |
|---|
| .. | .. |
|---|
| 1419 | 1375 | &tx_thr_num_pkt_prd); |
|---|
| 1420 | 1376 | device_property_read_u8(dev, "snps,tx-max-burst-prd", |
|---|
| 1421 | 1377 | &tx_max_burst_prd); |
|---|
| 1378 | + dwc->do_fifo_resize = device_property_read_bool(dev, |
|---|
| 1379 | + "tx-fifo-resize"); |
|---|
| 1380 | + if (dwc->do_fifo_resize) |
|---|
| 1381 | + device_property_read_u8(dev, "tx-fifo-max-num", |
|---|
| 1382 | + &tx_fifo_resize_max_num); |
|---|
| 1422 | 1383 | |
|---|
| 1423 | 1384 | dwc->disable_scramble_quirk = device_property_read_bool(dev, |
|---|
| 1424 | 1385 | "snps,disable_scramble_quirk"); |
|---|
| .. | .. |
|---|
| 1440 | 1401 | "snps,dis_u3_susphy_quirk"); |
|---|
| 1441 | 1402 | dwc->dis_u2_susphy_quirk = device_property_read_bool(dev, |
|---|
| 1442 | 1403 | "snps,dis_u2_susphy_quirk"); |
|---|
| 1443 | | - dwc->dis_u1u2_quirk = device_property_read_bool(dev, |
|---|
| 1444 | | - "snps,dis-u1u2-quirk"); |
|---|
| 1445 | 1404 | dwc->dis_enblslpm_quirk = device_property_read_bool(dev, |
|---|
| 1446 | 1405 | "snps,dis_enblslpm_quirk"); |
|---|
| 1406 | + dwc->dis_u1_entry_quirk = device_property_read_bool(dev, |
|---|
| 1407 | + "snps,dis-u1-entry-quirk"); |
|---|
| 1408 | + dwc->dis_u2_entry_quirk = device_property_read_bool(dev, |
|---|
| 1409 | + "snps,dis-u2-entry-quirk"); |
|---|
| 1447 | 1410 | dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev, |
|---|
| 1448 | 1411 | "snps,dis_rxdet_inp3_quirk"); |
|---|
| 1449 | 1412 | dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev, |
|---|
| .. | .. |
|---|
| 1454 | 1417 | "snps,dis-tx-ipgap-linecheck-quirk"); |
|---|
| 1455 | 1418 | dwc->parkmode_disable_ss_quirk = device_property_read_bool(dev, |
|---|
| 1456 | 1419 | "snps,parkmode-disable-ss-quirk"); |
|---|
| 1457 | | - dwc->xhci_slow_suspend_quirk = device_property_read_bool(dev, |
|---|
| 1458 | | - "snps,xhci-slow-suspend-quirk"); |
|---|
| 1459 | | - dwc->xhci_trb_ent_quirk = device_property_read_bool(dev, |
|---|
| 1460 | | - "snps,xhci-trb-ent-quirk"); |
|---|
| 1461 | | - dwc->dis_u3_autosuspend_quirk = device_property_read_bool(dev, |
|---|
| 1462 | | - "snps,dis-u3-autosuspend-quirk"); |
|---|
| 1420 | +#ifdef CONFIG_NO_GKI |
|---|
| 1421 | + dwc->parkmode_disable_hs_quirk = device_property_read_bool(dev, |
|---|
| 1422 | + "snps,parkmode-disable-hs-quirk"); |
|---|
| 1423 | +#endif |
|---|
| 1463 | 1424 | |
|---|
| 1464 | 1425 | dwc->tx_de_emphasis_quirk = device_property_read_bool(dev, |
|---|
| 1465 | 1426 | "snps,tx_de_emphasis_quirk"); |
|---|
| .. | .. |
|---|
| 1472 | 1433 | |
|---|
| 1473 | 1434 | dwc->dis_metastability_quirk = device_property_read_bool(dev, |
|---|
| 1474 | 1435 | "snps,dis_metastability_quirk"); |
|---|
| 1475 | | - dwc->needs_fifo_resize = device_property_read_bool(dev, |
|---|
| 1476 | | - "snps,tx-fifo-resize"); |
|---|
| 1477 | | - dwc->xhci_warm_reset_on_suspend_quirk = device_property_read_bool(dev, |
|---|
| 1478 | | - "snps,xhci-warm-reset-on-suspend-quirk"); |
|---|
| 1479 | | - dwc->uwk_en = device_property_read_bool(dev, |
|---|
| 1480 | | - "wakeup-source"); |
|---|
| 1436 | + |
|---|
| 1437 | + dwc->dis_split_quirk = device_property_read_bool(dev, |
|---|
| 1438 | + "snps,dis-split-quirk"); |
|---|
| 1481 | 1439 | |
|---|
| 1482 | 1440 | dwc->lpm_nyet_threshold = lpm_nyet_threshold; |
|---|
| 1483 | 1441 | dwc->tx_de_emphasis = tx_de_emphasis; |
|---|
| 1484 | 1442 | |
|---|
| 1485 | | - dwc->hird_threshold = hird_threshold |
|---|
| 1486 | | - | (dwc->is_utmi_l1_suspend << 4); |
|---|
| 1443 | + dwc->hird_threshold = hird_threshold; |
|---|
| 1487 | 1444 | |
|---|
| 1488 | 1445 | dwc->rx_thr_num_pkt_prd = rx_thr_num_pkt_prd; |
|---|
| 1489 | 1446 | dwc->rx_max_burst_prd = rx_max_burst_prd; |
|---|
| .. | .. |
|---|
| 1492 | 1449 | dwc->tx_max_burst_prd = tx_max_burst_prd; |
|---|
| 1493 | 1450 | |
|---|
| 1494 | 1451 | dwc->imod_interval = 0; |
|---|
| 1452 | + |
|---|
| 1453 | + dwc->tx_fifo_resize_max_num = tx_fifo_resize_max_num; |
|---|
| 1495 | 1454 | } |
|---|
| 1496 | 1455 | |
|---|
| 1497 | 1456 | /* check whether the core supports IMOD */ |
|---|
| 1498 | 1457 | bool dwc3_has_imod(struct dwc3 *dwc) |
|---|
| 1499 | 1458 | { |
|---|
| 1500 | | - return ((dwc3_is_usb3(dwc) && |
|---|
| 1501 | | - dwc->revision >= DWC3_REVISION_300A) || |
|---|
| 1502 | | - (dwc3_is_usb31(dwc) && |
|---|
| 1503 | | - dwc->revision >= DWC3_USB31_REVISION_120A)); |
|---|
| 1459 | + return DWC3_VER_IS_WITHIN(DWC3, 300A, ANY) || |
|---|
| 1460 | + DWC3_VER_IS_WITHIN(DWC31, 120A, ANY) || |
|---|
| 1461 | + DWC3_IP_IS(DWC32); |
|---|
| 1504 | 1462 | } |
|---|
| 1505 | 1463 | |
|---|
| 1506 | 1464 | static void dwc3_check_params(struct dwc3 *dwc) |
|---|
| 1507 | 1465 | { |
|---|
| 1508 | 1466 | struct device *dev = dwc->dev; |
|---|
| 1467 | + unsigned int hwparam_gen = |
|---|
| 1468 | + DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3); |
|---|
| 1509 | 1469 | |
|---|
| 1510 | 1470 | /* Check for proper value of imod_interval */ |
|---|
| 1511 | 1471 | if (dwc->imod_interval && !dwc3_has_imod(dwc)) { |
|---|
| .. | .. |
|---|
| 1521 | 1481 | * affected version. |
|---|
| 1522 | 1482 | */ |
|---|
| 1523 | 1483 | if (!dwc->imod_interval && |
|---|
| 1524 | | - (dwc->revision == DWC3_REVISION_300A)) |
|---|
| 1484 | + DWC3_VER_IS(DWC3, 300A)) |
|---|
| 1525 | 1485 | dwc->imod_interval = 1; |
|---|
| 1526 | 1486 | |
|---|
| 1527 | 1487 | /* Check the maximum_speed parameter */ |
|---|
| .. | .. |
|---|
| 1529 | 1489 | case USB_SPEED_LOW: |
|---|
| 1530 | 1490 | case USB_SPEED_FULL: |
|---|
| 1531 | 1491 | case USB_SPEED_HIGH: |
|---|
| 1492 | + break; |
|---|
| 1532 | 1493 | case USB_SPEED_SUPER: |
|---|
| 1494 | + if (hwparam_gen == DWC3_GHWPARAMS3_SSPHY_IFC_DIS) |
|---|
| 1495 | + dev_warn(dev, "UDC doesn't support Gen 1\n"); |
|---|
| 1496 | + break; |
|---|
| 1533 | 1497 | case USB_SPEED_SUPER_PLUS: |
|---|
| 1498 | + if ((DWC3_IP_IS(DWC32) && |
|---|
| 1499 | + hwparam_gen == DWC3_GHWPARAMS3_SSPHY_IFC_DIS) || |
|---|
| 1500 | + (!DWC3_IP_IS(DWC32) && |
|---|
| 1501 | + hwparam_gen != DWC3_GHWPARAMS3_SSPHY_IFC_GEN2)) |
|---|
| 1502 | + dev_warn(dev, "UDC doesn't support SSP\n"); |
|---|
| 1534 | 1503 | break; |
|---|
| 1535 | 1504 | default: |
|---|
| 1536 | 1505 | dev_err(dev, "invalid maximum_speed parameter %d\n", |
|---|
| 1537 | 1506 | dwc->maximum_speed); |
|---|
| 1538 | | - /* fall through */ |
|---|
| 1507 | + fallthrough; |
|---|
| 1539 | 1508 | case USB_SPEED_UNKNOWN: |
|---|
| 1540 | | - /* default to superspeed */ |
|---|
| 1541 | | - dwc->maximum_speed = USB_SPEED_SUPER; |
|---|
| 1542 | | - |
|---|
| 1543 | | - /* |
|---|
| 1544 | | - * default to superspeed plus if we are capable. |
|---|
| 1545 | | - */ |
|---|
| 1546 | | - if (dwc3_is_usb31(dwc) && |
|---|
| 1547 | | - (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) == |
|---|
| 1548 | | - DWC3_GHWPARAMS3_SSPHY_IFC_GEN2)) |
|---|
| 1509 | + switch (hwparam_gen) { |
|---|
| 1510 | + case DWC3_GHWPARAMS3_SSPHY_IFC_GEN2: |
|---|
| 1549 | 1511 | dwc->maximum_speed = USB_SPEED_SUPER_PLUS; |
|---|
| 1550 | | - |
|---|
| 1512 | + break; |
|---|
| 1513 | + case DWC3_GHWPARAMS3_SSPHY_IFC_GEN1: |
|---|
| 1514 | + if (DWC3_IP_IS(DWC32)) |
|---|
| 1515 | + dwc->maximum_speed = USB_SPEED_SUPER_PLUS; |
|---|
| 1516 | + else |
|---|
| 1517 | + dwc->maximum_speed = USB_SPEED_SUPER; |
|---|
| 1518 | + break; |
|---|
| 1519 | + case DWC3_GHWPARAMS3_SSPHY_IFC_DIS: |
|---|
| 1520 | + dwc->maximum_speed = USB_SPEED_HIGH; |
|---|
| 1521 | + break; |
|---|
| 1522 | + default: |
|---|
| 1523 | + dwc->maximum_speed = USB_SPEED_SUPER; |
|---|
| 1524 | + break; |
|---|
| 1525 | + } |
|---|
| 1551 | 1526 | break; |
|---|
| 1552 | 1527 | } |
|---|
| 1553 | | -} |
|---|
| 1554 | 1528 | |
|---|
| 1555 | | -static void dwc3_rockchip_async_probe(void *data, async_cookie_t cookie) |
|---|
| 1556 | | -{ |
|---|
| 1557 | | - struct dwc3 *dwc = data; |
|---|
| 1558 | | - struct device *dev = dwc->dev; |
|---|
| 1559 | | - int id; |
|---|
| 1560 | | - |
|---|
| 1561 | | - if (dwc->edev && !dwc->drd_connected) { |
|---|
| 1562 | | - id = extcon_get_state(dwc->edev, EXTCON_USB_HOST); |
|---|
| 1563 | | - if (id < 0) |
|---|
| 1564 | | - id = 0; |
|---|
| 1565 | | - dwc->current_dr_role = id ? DWC3_GCTL_PRTCAP_HOST : |
|---|
| 1566 | | - DWC3_GCTL_PRTCAP_DEVICE; |
|---|
| 1529 | + /* |
|---|
| 1530 | + * Currently the controller does not have visibility into the HW |
|---|
| 1531 | + * parameter to determine the maximum number of lanes the HW supports. |
|---|
| 1532 | + * If the number of lanes is not specified in the device property, then |
|---|
| 1533 | + * set the default to support dual-lane for DWC_usb32 and single-lane |
|---|
| 1534 | + * for DWC_usb31 for super-speed-plus. |
|---|
| 1535 | + */ |
|---|
| 1536 | + if (dwc->maximum_speed == USB_SPEED_SUPER_PLUS) { |
|---|
| 1537 | + switch (dwc->max_ssp_rate) { |
|---|
| 1538 | + case USB_SSP_GEN_2x1: |
|---|
| 1539 | + if (hwparam_gen == DWC3_GHWPARAMS3_SSPHY_IFC_GEN1) |
|---|
| 1540 | + dev_warn(dev, "UDC only supports Gen 1\n"); |
|---|
| 1541 | + break; |
|---|
| 1542 | + case USB_SSP_GEN_1x2: |
|---|
| 1543 | + case USB_SSP_GEN_2x2: |
|---|
| 1544 | + if (DWC3_IP_IS(DWC31)) |
|---|
| 1545 | + dev_warn(dev, "UDC only supports single lane\n"); |
|---|
| 1546 | + break; |
|---|
| 1547 | + case USB_SSP_GEN_UNKNOWN: |
|---|
| 1548 | + default: |
|---|
| 1549 | + switch (hwparam_gen) { |
|---|
| 1550 | + case DWC3_GHWPARAMS3_SSPHY_IFC_GEN2: |
|---|
| 1551 | + if (DWC3_IP_IS(DWC32)) |
|---|
| 1552 | + dwc->max_ssp_rate = USB_SSP_GEN_2x2; |
|---|
| 1553 | + else |
|---|
| 1554 | + dwc->max_ssp_rate = USB_SSP_GEN_2x1; |
|---|
| 1555 | + break; |
|---|
| 1556 | + case DWC3_GHWPARAMS3_SSPHY_IFC_GEN1: |
|---|
| 1557 | + if (DWC3_IP_IS(DWC32)) |
|---|
| 1558 | + dwc->max_ssp_rate = USB_SSP_GEN_1x2; |
|---|
| 1559 | + break; |
|---|
| 1560 | + } |
|---|
| 1561 | + break; |
|---|
| 1562 | + } |
|---|
| 1567 | 1563 | } |
|---|
| 1568 | | - |
|---|
| 1569 | | - pm_runtime_put_sync_suspend(dev); |
|---|
| 1570 | 1564 | } |
|---|
| 1571 | 1565 | |
|---|
| 1572 | 1566 | static int dwc3_probe(struct platform_device *pdev) |
|---|
| 1573 | 1567 | { |
|---|
| 1574 | 1568 | struct device *dev = &pdev->dev; |
|---|
| 1575 | 1569 | struct resource *res, dwc_res; |
|---|
| 1570 | + struct dwc3_vendor *vdwc; |
|---|
| 1576 | 1571 | struct dwc3 *dwc; |
|---|
| 1577 | 1572 | |
|---|
| 1578 | 1573 | int ret; |
|---|
| 1579 | 1574 | |
|---|
| 1580 | 1575 | void __iomem *regs; |
|---|
| 1581 | 1576 | |
|---|
| 1582 | | - dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL); |
|---|
| 1583 | | - if (!dwc) |
|---|
| 1577 | + vdwc = devm_kzalloc(dev, sizeof(*vdwc), GFP_KERNEL); |
|---|
| 1578 | + if (!vdwc) |
|---|
| 1584 | 1579 | return -ENOMEM; |
|---|
| 1585 | | - |
|---|
| 1586 | | - dwc->clks = devm_kmemdup(dev, dwc3_core_clks, sizeof(dwc3_core_clks), |
|---|
| 1587 | | - GFP_KERNEL); |
|---|
| 1588 | | - if (!dwc->clks) |
|---|
| 1589 | | - return -ENOMEM; |
|---|
| 1580 | + dwc = &vdwc->dwc; |
|---|
| 1590 | 1581 | |
|---|
| 1591 | 1582 | dwc->dev = dev; |
|---|
| 1592 | 1583 | |
|---|
| .. | .. |
|---|
| 1616 | 1607 | dwc->regs = regs; |
|---|
| 1617 | 1608 | dwc->regs_size = resource_size(&dwc_res); |
|---|
| 1618 | 1609 | |
|---|
| 1619 | | - dwc->reset = devm_reset_control_get_optional_shared(dev, NULL); |
|---|
| 1610 | + dwc3_get_properties(dwc); |
|---|
| 1611 | + |
|---|
| 1612 | + dwc->reset = devm_reset_control_array_get_optional_shared(dev); |
|---|
| 1620 | 1613 | if (IS_ERR(dwc->reset)) |
|---|
| 1621 | 1614 | return PTR_ERR(dwc->reset); |
|---|
| 1622 | 1615 | |
|---|
| 1623 | | - ret = reset_control_deassert(dwc->reset); |
|---|
| 1624 | | - if (ret) |
|---|
| 1625 | | - return ret; |
|---|
| 1626 | | - |
|---|
| 1627 | | - /* Reset the whole dwc3 controller */ |
|---|
| 1628 | | - ret = reset_control_assert(dwc->reset); |
|---|
| 1629 | | - if (ret) |
|---|
| 1630 | | - return ret; |
|---|
| 1631 | | - |
|---|
| 1632 | | - udelay(1); |
|---|
| 1633 | | - |
|---|
| 1634 | | - ret = reset_control_deassert(dwc->reset); |
|---|
| 1635 | | - if (ret) |
|---|
| 1636 | | - return ret; |
|---|
| 1637 | | - |
|---|
| 1638 | | - if (!dwc3_core_is_valid(dwc)) { |
|---|
| 1639 | | - dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n"); |
|---|
| 1640 | | - return -ENODEV; |
|---|
| 1641 | | - } |
|---|
| 1642 | | - |
|---|
| 1643 | | - dwc3_get_properties(dwc); |
|---|
| 1644 | | - |
|---|
| 1645 | 1616 | if (dev->of_node) { |
|---|
| 1646 | | - dwc->num_clks = ARRAY_SIZE(dwc3_core_clks); |
|---|
| 1647 | | - |
|---|
| 1648 | | - ret = clk_bulk_get(dev, dwc->num_clks, dwc->clks); |
|---|
| 1617 | + ret = devm_clk_bulk_get_all(dev, &dwc->clks); |
|---|
| 1649 | 1618 | if (ret == -EPROBE_DEFER) |
|---|
| 1650 | | - goto assert_reset; |
|---|
| 1619 | + return ret; |
|---|
| 1651 | 1620 | /* |
|---|
| 1652 | 1621 | * Clocks are optional, but new DT platforms should support all |
|---|
| 1653 | 1622 | * clocks as required by the DT-binding. |
|---|
| 1654 | 1623 | */ |
|---|
| 1655 | | - if (ret) |
|---|
| 1624 | + if (ret < 0) |
|---|
| 1656 | 1625 | dwc->num_clks = 0; |
|---|
| 1626 | + else |
|---|
| 1627 | + dwc->num_clks = ret; |
|---|
| 1628 | + |
|---|
| 1657 | 1629 | } |
|---|
| 1658 | 1630 | |
|---|
| 1659 | | - ret = clk_bulk_prepare(dwc->num_clks, dwc->clks); |
|---|
| 1631 | + ret = reset_control_deassert(dwc->reset); |
|---|
| 1660 | 1632 | if (ret) |
|---|
| 1661 | | - goto put_clks; |
|---|
| 1633 | + return ret; |
|---|
| 1662 | 1634 | |
|---|
| 1663 | | - ret = clk_bulk_enable(dwc->num_clks, dwc->clks); |
|---|
| 1635 | + ret = clk_bulk_prepare_enable(dwc->num_clks, dwc->clks); |
|---|
| 1664 | 1636 | if (ret) |
|---|
| 1665 | | - goto unprepare_clks; |
|---|
| 1637 | + goto assert_reset; |
|---|
| 1638 | + |
|---|
| 1639 | + if (!dwc3_core_is_valid(dwc)) { |
|---|
| 1640 | + dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n"); |
|---|
| 1641 | + ret = -ENODEV; |
|---|
| 1642 | + goto disable_clks; |
|---|
| 1643 | + } |
|---|
| 1666 | 1644 | |
|---|
| 1667 | 1645 | platform_set_drvdata(pdev, dwc); |
|---|
| 1668 | 1646 | dwc3_cache_hwparams(dwc); |
|---|
| 1669 | 1647 | |
|---|
| 1670 | 1648 | spin_lock_init(&dwc->lock); |
|---|
| 1649 | + mutex_init(&dwc->mutex); |
|---|
| 1671 | 1650 | |
|---|
| 1651 | + pm_runtime_get_noresume(dev); |
|---|
| 1672 | 1652 | pm_runtime_set_active(dev); |
|---|
| 1673 | 1653 | pm_runtime_use_autosuspend(dev); |
|---|
| 1674 | 1654 | pm_runtime_set_autosuspend_delay(dev, DWC3_DEFAULT_AUTOSUSPEND_DELAY); |
|---|
| 1675 | 1655 | pm_runtime_enable(dev); |
|---|
| 1676 | | - ret = pm_runtime_get_sync(dev); |
|---|
| 1677 | | - if (ret < 0) |
|---|
| 1678 | | - goto err1; |
|---|
| 1679 | 1656 | |
|---|
| 1680 | 1657 | pm_runtime_forbid(dev); |
|---|
| 1681 | 1658 | |
|---|
| .. | .. |
|---|
| 1690 | 1667 | if (ret) |
|---|
| 1691 | 1668 | goto err3; |
|---|
| 1692 | 1669 | |
|---|
| 1693 | | - if (dwc->dr_mode == USB_DR_MODE_OTG && |
|---|
| 1694 | | - of_device_is_compatible(dev->parent->of_node, |
|---|
| 1695 | | - "rockchip,rk3399-dwc3")) { |
|---|
| 1696 | | - pm_runtime_allow(dev); |
|---|
| 1697 | | - dwc->en_runtime = true; |
|---|
| 1698 | | - } |
|---|
| 1699 | | - |
|---|
| 1700 | 1670 | ret = dwc3_alloc_scratch_buffers(dwc); |
|---|
| 1701 | 1671 | if (ret) |
|---|
| 1702 | 1672 | goto err3; |
|---|
| 1703 | 1673 | |
|---|
| 1704 | 1674 | ret = dwc3_core_init(dwc); |
|---|
| 1705 | 1675 | if (ret) { |
|---|
| 1706 | | - if (ret != -EPROBE_DEFER) |
|---|
| 1707 | | - dev_err(dev, "failed to initialize core: %d\n", ret); |
|---|
| 1676 | + dev_err_probe(dev, ret, "failed to initialize core\n"); |
|---|
| 1708 | 1677 | goto err4; |
|---|
| 1709 | 1678 | } |
|---|
| 1710 | 1679 | |
|---|
| .. | .. |
|---|
| 1715 | 1684 | if (ret) |
|---|
| 1716 | 1685 | goto err5; |
|---|
| 1717 | 1686 | |
|---|
| 1718 | | - if (dwc->en_runtime) |
|---|
| 1719 | | - async_schedule(dwc3_rockchip_async_probe, dwc); |
|---|
| 1720 | | - else |
|---|
| 1687 | + if (dwc->dr_mode == USB_DR_MODE_OTG && |
|---|
| 1688 | + of_device_is_compatible(dev->parent->of_node, |
|---|
| 1689 | + "rockchip,rk3399-dwc3")) { |
|---|
| 1690 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
|---|
| 1691 | + pm_runtime_set_autosuspend_delay(dev, 100); |
|---|
| 1692 | +#endif |
|---|
| 1693 | + pm_runtime_allow(dev); |
|---|
| 1694 | + pm_runtime_put_sync_suspend(dev); |
|---|
| 1695 | + } else { |
|---|
| 1721 | 1696 | pm_runtime_put(dev); |
|---|
| 1697 | + } |
|---|
| 1722 | 1698 | |
|---|
| 1723 | 1699 | return 0; |
|---|
| 1724 | 1700 | |
|---|
| .. | .. |
|---|
| 1726 | 1702 | dwc3_debugfs_exit(dwc); |
|---|
| 1727 | 1703 | dwc3_event_buffers_cleanup(dwc); |
|---|
| 1728 | 1704 | |
|---|
| 1729 | | - usb_phy_shutdown(dwc->usb2_phy); |
|---|
| 1730 | | - usb_phy_shutdown(dwc->usb3_phy); |
|---|
| 1731 | | - phy_exit(dwc->usb2_generic_phy); |
|---|
| 1732 | | - phy_exit(dwc->usb3_generic_phy); |
|---|
| 1733 | | - |
|---|
| 1734 | 1705 | usb_phy_set_suspend(dwc->usb2_phy, 1); |
|---|
| 1735 | 1706 | usb_phy_set_suspend(dwc->usb3_phy, 1); |
|---|
| 1736 | 1707 | phy_power_off(dwc->usb2_generic_phy); |
|---|
| 1737 | 1708 | phy_power_off(dwc->usb3_generic_phy); |
|---|
| 1709 | + |
|---|
| 1710 | + usb_phy_shutdown(dwc->usb2_phy); |
|---|
| 1711 | + usb_phy_shutdown(dwc->usb3_phy); |
|---|
| 1712 | + phy_exit(dwc->usb2_generic_phy); |
|---|
| 1713 | + phy_exit(dwc->usb3_generic_phy); |
|---|
| 1738 | 1714 | |
|---|
| 1739 | 1715 | dwc3_ulpi_exit(dwc); |
|---|
| 1740 | 1716 | |
|---|
| .. | .. |
|---|
| 1745 | 1721 | dwc3_free_event_buffers(dwc); |
|---|
| 1746 | 1722 | |
|---|
| 1747 | 1723 | err2: |
|---|
| 1748 | | - pm_runtime_allow(&pdev->dev); |
|---|
| 1749 | | - |
|---|
| 1750 | | -err1: |
|---|
| 1751 | | - pm_runtime_put_sync(&pdev->dev); |
|---|
| 1752 | | - pm_runtime_disable(&pdev->dev); |
|---|
| 1753 | | - |
|---|
| 1754 | | - clk_bulk_disable(dwc->num_clks, dwc->clks); |
|---|
| 1755 | | -unprepare_clks: |
|---|
| 1756 | | - clk_bulk_unprepare(dwc->num_clks, dwc->clks); |
|---|
| 1757 | | -put_clks: |
|---|
| 1758 | | - clk_bulk_put(dwc->num_clks, dwc->clks); |
|---|
| 1724 | + pm_runtime_allow(dev); |
|---|
| 1725 | + pm_runtime_disable(dev); |
|---|
| 1726 | + pm_runtime_set_suspended(dev); |
|---|
| 1727 | + pm_runtime_put_noidle(dev); |
|---|
| 1728 | +disable_clks: |
|---|
| 1729 | + clk_bulk_disable_unprepare(dwc->num_clks, dwc->clks); |
|---|
| 1759 | 1730 | assert_reset: |
|---|
| 1760 | 1731 | reset_control_assert(dwc->reset); |
|---|
| 1732 | + |
|---|
| 1733 | + if (dwc->usb_psy) |
|---|
| 1734 | + power_supply_put(dwc->usb_psy); |
|---|
| 1761 | 1735 | |
|---|
| 1762 | 1736 | return ret; |
|---|
| 1763 | 1737 | } |
|---|
| .. | .. |
|---|
| 1774 | 1748 | dwc3_core_exit(dwc); |
|---|
| 1775 | 1749 | dwc3_ulpi_exit(dwc); |
|---|
| 1776 | 1750 | |
|---|
| 1751 | + pm_runtime_allow(&pdev->dev); |
|---|
| 1777 | 1752 | pm_runtime_disable(&pdev->dev); |
|---|
| 1778 | 1753 | pm_runtime_put_noidle(&pdev->dev); |
|---|
| 1754 | + /* |
|---|
| 1755 | + * HACK: Clear the driver data, which is currently accessed by parent |
|---|
| 1756 | + * glue drivers, before allowing the parent to suspend. |
|---|
| 1757 | + */ |
|---|
| 1758 | + platform_set_drvdata(pdev, NULL); |
|---|
| 1779 | 1759 | pm_runtime_set_suspended(&pdev->dev); |
|---|
| 1780 | 1760 | |
|---|
| 1781 | 1761 | dwc3_free_event_buffers(dwc); |
|---|
| 1782 | 1762 | dwc3_free_scratch_buffers(dwc); |
|---|
| 1783 | | - clk_bulk_put(dwc->num_clks, dwc->clks); |
|---|
| 1763 | + |
|---|
| 1764 | + if (dwc->usb_psy) |
|---|
| 1765 | + power_supply_put(dwc->usb_psy); |
|---|
| 1784 | 1766 | |
|---|
| 1785 | 1767 | return 0; |
|---|
| 1786 | 1768 | } |
|---|
| .. | .. |
|---|
| 1790 | 1772 | { |
|---|
| 1791 | 1773 | int ret; |
|---|
| 1792 | 1774 | |
|---|
| 1793 | | - if (!dwc->drd_connected && dwc->dr_mode == USB_DR_MODE_OTG) { |
|---|
| 1794 | | - ret = reset_control_deassert(dwc->reset); |
|---|
| 1795 | | - if (ret) |
|---|
| 1796 | | - return ret; |
|---|
| 1797 | | - } |
|---|
| 1775 | + ret = reset_control_deassert(dwc->reset); |
|---|
| 1776 | + if (ret) |
|---|
| 1777 | + return ret; |
|---|
| 1798 | 1778 | |
|---|
| 1799 | | - ret = clk_bulk_prepare(dwc->num_clks, dwc->clks); |
|---|
| 1779 | + ret = clk_bulk_prepare_enable(dwc->num_clks, dwc->clks); |
|---|
| 1800 | 1780 | if (ret) |
|---|
| 1801 | 1781 | goto assert_reset; |
|---|
| 1802 | | - |
|---|
| 1803 | | - ret = clk_bulk_enable(dwc->num_clks, dwc->clks); |
|---|
| 1804 | | - if (ret) |
|---|
| 1805 | | - goto unprepare_clks; |
|---|
| 1806 | 1782 | |
|---|
| 1807 | 1783 | ret = dwc3_core_init(dwc); |
|---|
| 1808 | 1784 | if (ret) |
|---|
| .. | .. |
|---|
| 1811 | 1787 | return 0; |
|---|
| 1812 | 1788 | |
|---|
| 1813 | 1789 | disable_clks: |
|---|
| 1814 | | - clk_bulk_disable(dwc->num_clks, dwc->clks); |
|---|
| 1815 | | -unprepare_clks: |
|---|
| 1816 | | - clk_bulk_unprepare(dwc->num_clks, dwc->clks); |
|---|
| 1790 | + clk_bulk_disable_unprepare(dwc->num_clks, dwc->clks); |
|---|
| 1817 | 1791 | assert_reset: |
|---|
| 1818 | | - if (!dwc->drd_connected && dwc->dr_mode == USB_DR_MODE_OTG) |
|---|
| 1819 | | - reset_control_assert(dwc->reset); |
|---|
| 1792 | + reset_control_assert(dwc->reset); |
|---|
| 1820 | 1793 | |
|---|
| 1821 | 1794 | return ret; |
|---|
| 1822 | 1795 | } |
|---|
| .. | .. |
|---|
| 1828 | 1801 | |
|---|
| 1829 | 1802 | switch (dwc->current_dr_role) { |
|---|
| 1830 | 1803 | case DWC3_GCTL_PRTCAP_DEVICE: |
|---|
| 1831 | | - spin_lock_irqsave(&dwc->lock, flags); |
|---|
| 1804 | + if (pm_runtime_suspended(dwc->dev)) |
|---|
| 1805 | + break; |
|---|
| 1832 | 1806 | dwc3_gadget_suspend(dwc); |
|---|
| 1833 | | - spin_unlock_irqrestore(&dwc->lock, flags); |
|---|
| 1834 | 1807 | synchronize_irq(dwc->irq_gadget); |
|---|
| 1835 | 1808 | dwc3_core_exit(dwc); |
|---|
| 1836 | 1809 | break; |
|---|
| 1837 | 1810 | case DWC3_GCTL_PRTCAP_HOST: |
|---|
| 1838 | | - if (!PMSG_IS_AUTO(msg) || dwc->en_runtime) { |
|---|
| 1811 | + if (!PMSG_IS_AUTO(msg)) { |
|---|
| 1839 | 1812 | dwc3_core_exit(dwc); |
|---|
| 1840 | 1813 | break; |
|---|
| 1841 | 1814 | } |
|---|
| .. | .. |
|---|
| 1871 | 1844 | dwc3_core_exit(dwc); |
|---|
| 1872 | 1845 | break; |
|---|
| 1873 | 1846 | default: |
|---|
| 1874 | | - /* do nothing */ |
|---|
| 1847 | + if (!pm_runtime_suspended(dwc->dev)) |
|---|
| 1848 | + dwc3_core_exit(dwc); |
|---|
| 1875 | 1849 | break; |
|---|
| 1876 | 1850 | } |
|---|
| 1877 | 1851 | |
|---|
| .. | .. |
|---|
| 1891 | 1865 | return ret; |
|---|
| 1892 | 1866 | |
|---|
| 1893 | 1867 | dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE); |
|---|
| 1894 | | - spin_lock_irqsave(&dwc->lock, flags); |
|---|
| 1895 | 1868 | dwc3_gadget_resume(dwc); |
|---|
| 1896 | | - spin_unlock_irqrestore(&dwc->lock, flags); |
|---|
| 1897 | 1869 | break; |
|---|
| 1898 | 1870 | case DWC3_GCTL_PRTCAP_HOST: |
|---|
| 1899 | | - if (!PMSG_IS_AUTO(msg) || dwc->en_runtime) { |
|---|
| 1871 | + if (!PMSG_IS_AUTO(msg)) { |
|---|
| 1900 | 1872 | ret = dwc3_core_init_for_resume(dwc); |
|---|
| 1901 | 1873 | if (ret) |
|---|
| 1902 | 1874 | return ret; |
|---|
| .. | .. |
|---|
| 1938 | 1910 | |
|---|
| 1939 | 1911 | break; |
|---|
| 1940 | 1912 | default: |
|---|
| 1941 | | - /* do nothing */ |
|---|
| 1913 | + ret = dwc3_core_init_for_resume(dwc); |
|---|
| 1914 | + if (ret) |
|---|
| 1915 | + return ret; |
|---|
| 1942 | 1916 | break; |
|---|
| 1943 | 1917 | } |
|---|
| 1944 | 1918 | |
|---|
| .. | .. |
|---|
| 2032 | 2006 | struct dwc3 *dwc = dev_get_drvdata(dev); |
|---|
| 2033 | 2007 | int ret; |
|---|
| 2034 | 2008 | |
|---|
| 2035 | | - if (dwc->uwk_en) { |
|---|
| 2036 | | - dwc3_gadget_disable_irq(dwc); |
|---|
| 2037 | | - synchronize_irq(dwc->irq_gadget); |
|---|
| 2038 | | - return 0; |
|---|
| 2039 | | - } |
|---|
| 2040 | | - |
|---|
| 2041 | 2009 | if (pm_runtime_suspended(dwc->dev)) |
|---|
| 2042 | 2010 | return 0; |
|---|
| 2043 | 2011 | |
|---|
| 2044 | 2012 | ret = dwc3_suspend_common(dwc, PMSG_SUSPEND); |
|---|
| 2045 | 2013 | if (ret) |
|---|
| 2046 | 2014 | return ret; |
|---|
| 2047 | | - |
|---|
| 2048 | | - /* |
|---|
| 2049 | | - * If link state is Rx.Detect, it means that |
|---|
| 2050 | | - * no usb device is connecting with the DWC3 |
|---|
| 2051 | | - * Host, and need to power off the USB3 PHY. |
|---|
| 2052 | | - * |
|---|
| 2053 | | - * If link state is in other state, like U0 |
|---|
| 2054 | | - * or U3 state, it means that at least one |
|---|
| 2055 | | - * USB3 device is connecting with the Host |
|---|
| 2056 | | - * port, in this case, we don't power off |
|---|
| 2057 | | - * the USB3 PHY because some USB3 PHYs (like |
|---|
| 2058 | | - * RK3399 Type-C USB3 PHY) require that the |
|---|
| 2059 | | - * power on operation must be done while the |
|---|
| 2060 | | - * DWC3 controller is in P2 state, but the |
|---|
| 2061 | | - * state is in P0 after resume with a USB3 |
|---|
| 2062 | | - * device connected. So we set the USB3 PHY |
|---|
| 2063 | | - * in power on state in this case. |
|---|
| 2064 | | - */ |
|---|
| 2065 | | - dwc->link_state = dwc3_gadget_get_link_state(dwc); |
|---|
| 2066 | | - if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST && |
|---|
| 2067 | | - dwc->link_state == DWC3_LINK_STATE_RX_DET) |
|---|
| 2068 | | - phy_power_off(dwc->usb3_generic_phy); |
|---|
| 2069 | 2015 | |
|---|
| 2070 | 2016 | pinctrl_pm_select_sleep_state(dev); |
|---|
| 2071 | 2017 | |
|---|
| .. | .. |
|---|
| 2077 | 2023 | struct dwc3 *dwc = dev_get_drvdata(dev); |
|---|
| 2078 | 2024 | int ret; |
|---|
| 2079 | 2025 | |
|---|
| 2080 | | - if (dwc->uwk_en) { |
|---|
| 2081 | | - dwc3_gadget_enable_irq(dwc); |
|---|
| 2082 | | - return 0; |
|---|
| 2083 | | - } |
|---|
| 2084 | | - |
|---|
| 2085 | 2026 | if (pm_runtime_suspended(dwc->dev)) |
|---|
| 2086 | 2027 | return 0; |
|---|
| 2087 | 2028 | |
|---|
| 2088 | 2029 | pinctrl_pm_select_default_state(dev); |
|---|
| 2089 | | - |
|---|
| 2090 | | - if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST && |
|---|
| 2091 | | - dwc->link_state == DWC3_LINK_STATE_RX_DET) |
|---|
| 2092 | | - phy_power_on(dwc->usb3_generic_phy); |
|---|
| 2093 | 2030 | |
|---|
| 2094 | 2031 | ret = dwc3_resume_common(dwc, PMSG_RESUME); |
|---|
| 2095 | 2032 | if (ret) |
|---|
| .. | .. |
|---|
| 2101 | 2038 | |
|---|
| 2102 | 2039 | return 0; |
|---|
| 2103 | 2040 | } |
|---|
| 2041 | + |
|---|
| 2042 | +static void dwc3_complete(struct device *dev) |
|---|
| 2043 | +{ |
|---|
| 2044 | + struct dwc3 *dwc = dev_get_drvdata(dev); |
|---|
| 2045 | + u32 reg; |
|---|
| 2046 | + |
|---|
| 2047 | + if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST && |
|---|
| 2048 | + dwc->dis_split_quirk) { |
|---|
| 2049 | + reg = dwc3_readl(dwc->regs, DWC3_GUCTL3); |
|---|
| 2050 | + reg |= DWC3_GUCTL3_SPLITDISABLE; |
|---|
| 2051 | + dwc3_writel(dwc->regs, DWC3_GUCTL3, reg); |
|---|
| 2052 | + } |
|---|
| 2053 | +} |
|---|
| 2054 | +#else |
|---|
| 2055 | +#define dwc3_complete NULL |
|---|
| 2104 | 2056 | #endif /* CONFIG_PM_SLEEP */ |
|---|
| 2105 | 2057 | |
|---|
| 2106 | 2058 | static const struct dev_pm_ops dwc3_dev_pm_ops = { |
|---|
| 2107 | 2059 | SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume) |
|---|
| 2060 | + .complete = dwc3_complete, |
|---|
| 2108 | 2061 | SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume, |
|---|
| 2109 | 2062 | dwc3_runtime_idle) |
|---|
| 2110 | 2063 | }; |
|---|