| .. | .. |
|---|
| 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; |
|---|
| 121 | 124 | |
|---|
| 122 | | - if (dwc->dr_mode != USB_DR_MODE_OTG) |
|---|
| 123 | | - return; |
|---|
| 125 | + mutex_lock(&dwc->mutex); |
|---|
| 126 | + |
|---|
| 127 | + pm_runtime_get_sync(dwc->dev); |
|---|
| 128 | + |
|---|
| 129 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
|---|
| 130 | + if (dwc->desired_role_sw_mode == USB_DR_MODE_PERIPHERAL && |
|---|
| 131 | + dwc->desired_role_sw_mode != dwc->current_role_sw_mode) |
|---|
| 132 | + pm_runtime_get(dwc->dev); |
|---|
| 133 | + else if ((dwc->desired_role_sw_mode == USB_DR_MODE_UNKNOWN || |
|---|
| 134 | + dwc->desired_role_sw_mode == USB_DR_MODE_HOST) && |
|---|
| 135 | + dwc->current_role_sw_mode == USB_DR_MODE_PERIPHERAL) |
|---|
| 136 | + pm_runtime_put(dwc->dev); |
|---|
| 137 | + |
|---|
| 138 | + dwc->current_role_sw_mode = dwc->desired_role_sw_mode; |
|---|
| 139 | +#endif |
|---|
| 124 | 140 | |
|---|
| 125 | 141 | if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG) |
|---|
| 126 | 142 | dwc3_otg_update(dwc, 0); |
|---|
| 127 | 143 | |
|---|
| 128 | 144 | if (!dwc->desired_dr_role) |
|---|
| 129 | | - return; |
|---|
| 130 | | - |
|---|
| 131 | | - if (dwc->en_runtime) |
|---|
| 132 | | - goto runtime; |
|---|
| 145 | + goto out; |
|---|
| 133 | 146 | |
|---|
| 134 | 147 | if (dwc->desired_dr_role == dwc->current_dr_role) |
|---|
| 135 | | - return; |
|---|
| 148 | + goto out; |
|---|
| 136 | 149 | |
|---|
| 137 | 150 | if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev) |
|---|
| 138 | | - return; |
|---|
| 151 | + goto out; |
|---|
| 139 | 152 | |
|---|
| 140 | 153 | switch (dwc->current_dr_role) { |
|---|
| 141 | 154 | case DWC3_GCTL_PRTCAP_HOST: |
|---|
| .. | .. |
|---|
| 156 | 169 | break; |
|---|
| 157 | 170 | } |
|---|
| 158 | 171 | |
|---|
| 172 | + /* |
|---|
| 173 | + * When current_dr_role is not set, there's no role switching. |
|---|
| 174 | + * Only perform GCTL.CoreSoftReset when there's DRD role switching. |
|---|
| 175 | + */ |
|---|
| 176 | + if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) || |
|---|
| 177 | + DWC3_VER_IS_PRIOR(DWC31, 190A)) && |
|---|
| 178 | + dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) { |
|---|
| 179 | + reg = dwc3_readl(dwc->regs, DWC3_GCTL); |
|---|
| 180 | + reg |= DWC3_GCTL_CORESOFTRESET; |
|---|
| 181 | + dwc3_writel(dwc->regs, DWC3_GCTL, reg); |
|---|
| 182 | + |
|---|
| 183 | + /* |
|---|
| 184 | + * Wait for internal clocks to synchronized. DWC_usb31 and |
|---|
| 185 | + * DWC_usb32 may need at least 50ms (less for DWC_usb3). To |
|---|
| 186 | + * keep it consistent across different IPs, let's wait up to |
|---|
| 187 | + * 100ms before clearing GCTL.CORESOFTRESET. |
|---|
| 188 | + */ |
|---|
| 189 | + msleep(100); |
|---|
| 190 | + |
|---|
| 191 | + reg = dwc3_readl(dwc->regs, DWC3_GCTL); |
|---|
| 192 | + reg &= ~DWC3_GCTL_CORESOFTRESET; |
|---|
| 193 | + dwc3_writel(dwc->regs, DWC3_GCTL, reg); |
|---|
| 194 | + } |
|---|
| 195 | + |
|---|
| 159 | 196 | spin_lock_irqsave(&dwc->lock, flags); |
|---|
| 160 | 197 | |
|---|
| 161 | 198 | dwc3_set_prtcap(dwc, dwc->desired_dr_role); |
|---|
| .. | .. |
|---|
| 172 | 209 | otg_set_vbus(dwc->usb2_phy->otg, true); |
|---|
| 173 | 210 | phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST); |
|---|
| 174 | 211 | 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); |
|---|
| 212 | + if (dwc->dis_split_quirk) { |
|---|
| 213 | + reg = dwc3_readl(dwc->regs, DWC3_GUCTL3); |
|---|
| 214 | + reg |= DWC3_GUCTL3_SPLITDISABLE; |
|---|
| 215 | + dwc3_writel(dwc->regs, DWC3_GUCTL3, reg); |
|---|
| 216 | + } |
|---|
| 178 | 217 | } |
|---|
| 179 | 218 | break; |
|---|
| 180 | 219 | case DWC3_GCTL_PRTCAP_DEVICE: |
|---|
| 220 | + reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
|---|
| 221 | + reg |= DWC3_DCTL_CSFTRST; |
|---|
| 222 | + dwc3_writel(dwc->regs, DWC3_DCTL, reg); |
|---|
| 223 | + |
|---|
| 224 | + if (DWC3_VER_IS_WITHIN(DWC31, 190A, ANY) || DWC3_IP_IS(DWC32)) |
|---|
| 225 | + retries = 10; |
|---|
| 226 | + |
|---|
| 227 | + do { |
|---|
| 228 | + reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
|---|
| 229 | + if (!(reg & DWC3_DCTL_CSFTRST)) |
|---|
| 230 | + goto done; |
|---|
| 231 | + |
|---|
| 232 | + if (DWC3_VER_IS_WITHIN(DWC31, 190A, ANY) || DWC3_IP_IS(DWC32)) |
|---|
| 233 | + msleep(20); |
|---|
| 234 | + else |
|---|
| 235 | + udelay(1); |
|---|
| 236 | + } while (--retries); |
|---|
| 237 | +done: |
|---|
| 238 | + if (DWC3_VER_IS_WITHIN(DWC31, ANY, 180A)) |
|---|
| 239 | + msleep(50); |
|---|
| 240 | + |
|---|
| 181 | 241 | dwc3_event_buffers_setup(dwc); |
|---|
| 182 | 242 | |
|---|
| 183 | 243 | if (dwc->usb2_phy) |
|---|
| .. | .. |
|---|
| 197 | 257 | break; |
|---|
| 198 | 258 | } |
|---|
| 199 | 259 | |
|---|
| 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 | | - } |
|---|
| 260 | +out: |
|---|
| 261 | + pm_runtime_mark_last_busy(dwc->dev); |
|---|
| 262 | + pm_runtime_put_autosuspend(dwc->dev); |
|---|
| 263 | + mutex_unlock(&dwc->mutex); |
|---|
| 312 | 264 | } |
|---|
| 313 | 265 | |
|---|
| 314 | 266 | void dwc3_set_mode(struct dwc3 *dwc, u32 mode) |
|---|
| 315 | 267 | { |
|---|
| 316 | 268 | unsigned long flags; |
|---|
| 269 | + |
|---|
| 270 | + if (dwc->dr_mode != USB_DR_MODE_OTG) |
|---|
| 271 | + return; |
|---|
| 317 | 272 | |
|---|
| 318 | 273 | spin_lock_irqsave(&dwc->lock, flags); |
|---|
| 319 | 274 | dwc->desired_dr_role = mode; |
|---|
| .. | .. |
|---|
| 340 | 295 | * dwc3_core_soft_reset - Issues core soft reset and PHY reset |
|---|
| 341 | 296 | * @dwc: pointer to our context structure |
|---|
| 342 | 297 | */ |
|---|
| 343 | | -static int dwc3_core_soft_reset(struct dwc3 *dwc) |
|---|
| 298 | +int dwc3_core_soft_reset(struct dwc3 *dwc) |
|---|
| 344 | 299 | { |
|---|
| 345 | 300 | u32 reg; |
|---|
| 346 | 301 | 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 | 302 | |
|---|
| 361 | 303 | /* |
|---|
| 362 | 304 | * We're resetting only the device side because, if we're in host mode, |
|---|
| .. | .. |
|---|
| 368 | 310 | |
|---|
| 369 | 311 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
|---|
| 370 | 312 | reg |= DWC3_DCTL_CSFTRST; |
|---|
| 371 | | - dwc3_writel(dwc->regs, DWC3_DCTL, reg); |
|---|
| 313 | + reg &= ~DWC3_DCTL_RUN_STOP; |
|---|
| 314 | + dwc3_gadget_dctl_write_safe(dwc, reg); |
|---|
| 315 | + |
|---|
| 316 | + /* |
|---|
| 317 | + * For DWC_usb31 controller 1.90a and later, the DCTL.CSFRST bit |
|---|
| 318 | + * is cleared only after all the clocks are synchronized. This can |
|---|
| 319 | + * take a little more than 50ms. Set the polling rate at 20ms |
|---|
| 320 | + * for 10 times instead. |
|---|
| 321 | + */ |
|---|
| 322 | + if (DWC3_VER_IS_WITHIN(DWC31, 190A, ANY) || DWC3_IP_IS(DWC32)) |
|---|
| 323 | + retries = 10; |
|---|
| 372 | 324 | |
|---|
| 373 | 325 | do { |
|---|
| 374 | 326 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
|---|
| 375 | 327 | if (!(reg & DWC3_DCTL_CSFTRST)) |
|---|
| 376 | 328 | goto done; |
|---|
| 377 | 329 | |
|---|
| 378 | | - udelay(1); |
|---|
| 330 | + if (DWC3_VER_IS_WITHIN(DWC31, 190A, ANY) || DWC3_IP_IS(DWC32)) |
|---|
| 331 | + msleep(20); |
|---|
| 332 | + else |
|---|
| 333 | + udelay(1); |
|---|
| 379 | 334 | } while (--retries); |
|---|
| 380 | 335 | |
|---|
| 381 | | - phy_exit(dwc->usb3_generic_phy); |
|---|
| 382 | | - phy_exit(dwc->usb2_generic_phy); |
|---|
| 383 | | - |
|---|
| 336 | + dev_warn(dwc->dev, "DWC3 controller soft reset failed.\n"); |
|---|
| 384 | 337 | return -ETIMEDOUT; |
|---|
| 385 | 338 | |
|---|
| 386 | 339 | done: |
|---|
| 387 | 340 | /* |
|---|
| 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. |
|---|
| 341 | + * For DWC_usb31 controller 1.80a and prior, once DCTL.CSFRST bit |
|---|
| 342 | + * is cleared, we must wait at least 50ms before accessing the PHY |
|---|
| 343 | + * domain (synchronization delay). |
|---|
| 391 | 344 | */ |
|---|
| 392 | | - if (dwc3_is_usb31(dwc)) |
|---|
| 345 | + if (DWC3_VER_IS_WITHIN(DWC31, ANY, 180A)) |
|---|
| 393 | 346 | msleep(50); |
|---|
| 394 | 347 | |
|---|
| 395 | 348 | return 0; |
|---|
| 396 | 349 | } |
|---|
| 397 | | - |
|---|
| 398 | | -static const struct clk_bulk_data dwc3_core_clks[] = { |
|---|
| 399 | | - { .id = "ref" }, |
|---|
| 400 | | - { .id = "bus_early" }, |
|---|
| 401 | | - { .id = "suspend" }, |
|---|
| 402 | | -}; |
|---|
| 403 | 350 | |
|---|
| 404 | 351 | /* |
|---|
| 405 | 352 | * dwc3_frame_length_adjustment - Adjusts frame length if required |
|---|
| .. | .. |
|---|
| 410 | 357 | u32 reg; |
|---|
| 411 | 358 | u32 dft; |
|---|
| 412 | 359 | |
|---|
| 413 | | - if (dwc->revision < DWC3_REVISION_250A) |
|---|
| 360 | + if (DWC3_VER_IS_PRIOR(DWC3, 250A)) |
|---|
| 414 | 361 | return; |
|---|
| 415 | 362 | |
|---|
| 416 | 363 | if (dwc->fladj == 0) |
|---|
| .. | .. |
|---|
| 445 | 392 | * otherwise ERR_PTR(errno). |
|---|
| 446 | 393 | */ |
|---|
| 447 | 394 | static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc, |
|---|
| 448 | | - unsigned length) |
|---|
| 395 | + unsigned int length) |
|---|
| 449 | 396 | { |
|---|
| 450 | 397 | struct dwc3_event_buffer *evt; |
|---|
| 451 | 398 | |
|---|
| .. | .. |
|---|
| 488 | 435 | * Returns 0 on success otherwise negative errno. In the error case, dwc |
|---|
| 489 | 436 | * may contain some buffers allocated but not all which were requested. |
|---|
| 490 | 437 | */ |
|---|
| 491 | | -static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length) |
|---|
| 438 | +static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned int length) |
|---|
| 492 | 439 | { |
|---|
| 493 | 440 | struct dwc3_event_buffer *evt; |
|---|
| 494 | 441 | |
|---|
| .. | .. |
|---|
| 644 | 591 | parms->hwparams6 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6); |
|---|
| 645 | 592 | parms->hwparams7 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS7); |
|---|
| 646 | 593 | parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8); |
|---|
| 594 | + |
|---|
| 595 | + if (DWC3_IP_IS(DWC32)) |
|---|
| 596 | + parms->hwparams9 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS9); |
|---|
| 647 | 597 | } |
|---|
| 648 | 598 | |
|---|
| 649 | 599 | static int dwc3_core_ulpi_init(struct dwc3 *dwc) |
|---|
| .. | .. |
|---|
| 672 | 622 | */ |
|---|
| 673 | 623 | static int dwc3_phy_setup(struct dwc3 *dwc) |
|---|
| 674 | 624 | { |
|---|
| 625 | + unsigned int hw_mode; |
|---|
| 675 | 626 | u32 reg; |
|---|
| 627 | + |
|---|
| 628 | + hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); |
|---|
| 676 | 629 | |
|---|
| 677 | 630 | reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); |
|---|
| 678 | 631 | |
|---|
| .. | .. |
|---|
| 688 | 641 | * will be '0' when the core is reset. Application needs to set it |
|---|
| 689 | 642 | * to '1' after the core initialization is completed. |
|---|
| 690 | 643 | */ |
|---|
| 691 | | - if (dwc->revision > DWC3_REVISION_194A) |
|---|
| 644 | + if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) |
|---|
| 692 | 645 | reg |= DWC3_GUSB3PIPECTL_SUSPHY; |
|---|
| 646 | + |
|---|
| 647 | + /* |
|---|
| 648 | + * For DRD controllers, GUSB3PIPECTL.SUSPENDENABLE must be cleared after |
|---|
| 649 | + * power-on reset, and it can be set after core initialization, which is |
|---|
| 650 | + * after device soft-reset during initialization. |
|---|
| 651 | + */ |
|---|
| 652 | + if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD) |
|---|
| 653 | + reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; |
|---|
| 693 | 654 | |
|---|
| 694 | 655 | if (dwc->u2ss_inp3_quirk) |
|---|
| 695 | 656 | reg |= DWC3_GUSB3PIPECTL_U2SSINP3OK; |
|---|
| .. | .. |
|---|
| 741 | 702 | if (!(reg & DWC3_GUSB2PHYCFG_ULPI_UTMI)) |
|---|
| 742 | 703 | break; |
|---|
| 743 | 704 | } |
|---|
| 744 | | - /* FALLTHROUGH */ |
|---|
| 705 | + fallthrough; |
|---|
| 745 | 706 | case DWC3_GHWPARAMS3_HSPHY_IFC_ULPI: |
|---|
| 746 | | - /* FALLTHROUGH */ |
|---|
| 747 | 707 | default: |
|---|
| 748 | 708 | break; |
|---|
| 749 | 709 | } |
|---|
| .. | .. |
|---|
| 771 | 731 | * be '0' when the core is reset. Application needs to set it to |
|---|
| 772 | 732 | * '1' after the core initialization is completed. |
|---|
| 773 | 733 | */ |
|---|
| 774 | | - if (dwc->revision > DWC3_REVISION_194A) |
|---|
| 734 | + if (!DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) |
|---|
| 775 | 735 | reg |= DWC3_GUSB2PHYCFG_SUSPHY; |
|---|
| 736 | + |
|---|
| 737 | + /* |
|---|
| 738 | + * For DRD controllers, GUSB2PHYCFG.SUSPHY must be cleared after |
|---|
| 739 | + * power-on reset, and it can be set after core initialization, which is |
|---|
| 740 | + * after device soft-reset during initialization. |
|---|
| 741 | + */ |
|---|
| 742 | + if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD) |
|---|
| 743 | + reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; |
|---|
| 776 | 744 | |
|---|
| 777 | 745 | if (dwc->dis_u2_susphy_quirk) |
|---|
| 778 | 746 | reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; |
|---|
| .. | .. |
|---|
| 794 | 762 | { |
|---|
| 795 | 763 | dwc3_event_buffers_cleanup(dwc); |
|---|
| 796 | 764 | |
|---|
| 765 | + usb_phy_set_suspend(dwc->usb2_phy, 1); |
|---|
| 766 | + usb_phy_set_suspend(dwc->usb3_phy, 1); |
|---|
| 767 | + phy_power_off(dwc->usb2_generic_phy); |
|---|
| 768 | + phy_power_off(dwc->usb3_generic_phy); |
|---|
| 769 | + |
|---|
| 797 | 770 | usb_phy_shutdown(dwc->usb2_phy); |
|---|
| 798 | 771 | usb_phy_shutdown(dwc->usb3_phy); |
|---|
| 799 | 772 | phy_exit(dwc->usb2_generic_phy); |
|---|
| 800 | 773 | phy_exit(dwc->usb3_generic_phy); |
|---|
| 801 | 774 | |
|---|
| 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); |
|---|
| 775 | + clk_bulk_disable_unprepare(dwc->num_clks, dwc->clks); |
|---|
| 776 | + reset_control_assert(dwc->reset); |
|---|
| 811 | 777 | } |
|---|
| 812 | 778 | |
|---|
| 813 | 779 | static bool dwc3_core_is_valid(struct dwc3 *dwc) |
|---|
| .. | .. |
|---|
| 815 | 781 | u32 reg; |
|---|
| 816 | 782 | |
|---|
| 817 | 783 | reg = dwc3_readl(dwc->regs, DWC3_GSNPSID); |
|---|
| 784 | + dwc->ip = DWC3_GSNPS_ID(reg); |
|---|
| 818 | 785 | |
|---|
| 819 | 786 | /* This should read as U3 followed by revision number */ |
|---|
| 820 | | - if ((reg & DWC3_GSNPSID_MASK) == 0x55330000) { |
|---|
| 821 | | - /* Detected DWC_usb3 IP */ |
|---|
| 787 | + if (DWC3_IP_IS(DWC3)) { |
|---|
| 822 | 788 | dwc->revision = reg; |
|---|
| 823 | | - } else if ((reg & DWC3_GSNPSID_MASK) == 0x33310000) { |
|---|
| 824 | | - /* Detected DWC_usb31 IP */ |
|---|
| 789 | + } else if (DWC3_IP_IS(DWC31) || DWC3_IP_IS(DWC32)) { |
|---|
| 825 | 790 | dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER); |
|---|
| 826 | | - dwc->revision |= DWC3_REVISION_IS_DWC31; |
|---|
| 827 | 791 | dwc->version_type = dwc3_readl(dwc->regs, DWC3_VER_TYPE); |
|---|
| 828 | 792 | } else { |
|---|
| 829 | 793 | return false; |
|---|
| .. | .. |
|---|
| 856 | 820 | */ |
|---|
| 857 | 821 | if ((dwc->dr_mode == USB_DR_MODE_HOST || |
|---|
| 858 | 822 | dwc->dr_mode == USB_DR_MODE_OTG) && |
|---|
| 859 | | - (dwc->revision >= DWC3_REVISION_210A && |
|---|
| 860 | | - dwc->revision <= DWC3_REVISION_250A)) |
|---|
| 823 | + DWC3_VER_IS_WITHIN(DWC3, 210A, 250A)) |
|---|
| 861 | 824 | reg |= DWC3_GCTL_DSBLCLKGTNG | DWC3_GCTL_SOFITPSYNC; |
|---|
| 862 | 825 | else |
|---|
| 863 | 826 | reg &= ~DWC3_GCTL_DSBLCLKGTNG; |
|---|
| .. | .. |
|---|
| 879 | 842 | |
|---|
| 880 | 843 | /* check if current dwc3 is on simulation board */ |
|---|
| 881 | 844 | if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) { |
|---|
| 882 | | - dev_info(dwc->dev, "Running with FPGA optmizations\n"); |
|---|
| 845 | + dev_info(dwc->dev, "Running with FPGA optimizations\n"); |
|---|
| 883 | 846 | dwc->is_fpga = true; |
|---|
| 884 | 847 | } |
|---|
| 885 | 848 | |
|---|
| .. | .. |
|---|
| 900 | 863 | * and falls back to high-speed mode which causes |
|---|
| 901 | 864 | * the device to enter a Connect/Disconnect loop |
|---|
| 902 | 865 | */ |
|---|
| 903 | | - if (dwc->revision < DWC3_REVISION_190A) |
|---|
| 866 | + if (DWC3_VER_IS_PRIOR(DWC3, 190A)) |
|---|
| 904 | 867 | reg |= DWC3_GCTL_U2RSTECN; |
|---|
| 905 | 868 | |
|---|
| 906 | 869 | dwc3_writel(dwc->regs, DWC3_GCTL, reg); |
|---|
| .. | .. |
|---|
| 932 | 895 | * result = 1, means INCRx burst mode supported. |
|---|
| 933 | 896 | * result > 1, means undefined length burst mode supported. |
|---|
| 934 | 897 | */ |
|---|
| 935 | | - ntype = device_property_read_u32_array(dev, |
|---|
| 936 | | - "snps,incr-burst-type-adjustment", NULL, 0); |
|---|
| 898 | + ntype = device_property_count_u32(dev, "snps,incr-burst-type-adjustment"); |
|---|
| 937 | 899 | if (ntype <= 0) |
|---|
| 938 | 900 | return; |
|---|
| 939 | 901 | |
|---|
| .. | .. |
|---|
| 1012 | 974 | */ |
|---|
| 1013 | 975 | static int dwc3_core_init(struct dwc3 *dwc) |
|---|
| 1014 | 976 | { |
|---|
| 977 | + unsigned int hw_mode; |
|---|
| 1015 | 978 | u32 reg; |
|---|
| 1016 | 979 | int ret; |
|---|
| 980 | + |
|---|
| 981 | + hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); |
|---|
| 1017 | 982 | |
|---|
| 1018 | 983 | /* |
|---|
| 1019 | 984 | * Write Linux Version Code to our GUID register so it's easy to figure |
|---|
| 1020 | 985 | * out which kernel version a bug was found. |
|---|
| 1021 | 986 | */ |
|---|
| 1022 | 987 | dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE); |
|---|
| 1023 | | - |
|---|
| 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 | 988 | |
|---|
| 1031 | 989 | ret = dwc3_phy_setup(dwc); |
|---|
| 1032 | 990 | if (ret) |
|---|
| .. | .. |
|---|
| 1046 | 1004 | dwc->phys_ready = true; |
|---|
| 1047 | 1005 | } |
|---|
| 1048 | 1006 | |
|---|
| 1007 | + usb_phy_init(dwc->usb2_phy); |
|---|
| 1008 | + usb_phy_init(dwc->usb3_phy); |
|---|
| 1009 | + ret = phy_init(dwc->usb2_generic_phy); |
|---|
| 1010 | + if (ret < 0) |
|---|
| 1011 | + goto err0a; |
|---|
| 1012 | + |
|---|
| 1013 | + ret = phy_init(dwc->usb3_generic_phy); |
|---|
| 1014 | + if (ret < 0) { |
|---|
| 1015 | + phy_exit(dwc->usb2_generic_phy); |
|---|
| 1016 | + goto err0a; |
|---|
| 1017 | + } |
|---|
| 1018 | + |
|---|
| 1049 | 1019 | ret = dwc3_core_soft_reset(dwc); |
|---|
| 1050 | 1020 | if (ret) |
|---|
| 1051 | | - goto err0a; |
|---|
| 1021 | + goto err1; |
|---|
| 1022 | + |
|---|
| 1023 | + if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD && |
|---|
| 1024 | + !DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) { |
|---|
| 1025 | + if (!dwc->dis_u3_susphy_quirk) { |
|---|
| 1026 | + reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); |
|---|
| 1027 | + reg |= DWC3_GUSB3PIPECTL_SUSPHY; |
|---|
| 1028 | + dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg); |
|---|
| 1029 | + } |
|---|
| 1030 | + |
|---|
| 1031 | + if (!dwc->dis_u2_susphy_quirk) { |
|---|
| 1032 | + reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); |
|---|
| 1033 | + reg |= DWC3_GUSB2PHYCFG_SUSPHY; |
|---|
| 1034 | + dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); |
|---|
| 1035 | + } |
|---|
| 1036 | + } |
|---|
| 1052 | 1037 | |
|---|
| 1053 | 1038 | dwc3_core_setup_global_control(dwc); |
|---|
| 1054 | 1039 | dwc3_core_num_eps(dwc); |
|---|
| .. | .. |
|---|
| 1083 | 1068 | * the DWC_usb3 controller. It is NOT available in the |
|---|
| 1084 | 1069 | * DWC_usb31 controller. |
|---|
| 1085 | 1070 | */ |
|---|
| 1086 | | - if (!dwc3_is_usb31(dwc) && dwc->revision >= DWC3_REVISION_310A) { |
|---|
| 1071 | + if (DWC3_VER_IS_WITHIN(DWC3, 310A, ANY)) { |
|---|
| 1087 | 1072 | reg = dwc3_readl(dwc->regs, DWC3_GUCTL2); |
|---|
| 1088 | 1073 | reg |= DWC3_GUCTL2_RST_ACTBITLATER; |
|---|
| 1089 | 1074 | dwc3_writel(dwc->regs, DWC3_GUCTL2, reg); |
|---|
| 1090 | 1075 | } |
|---|
| 1091 | 1076 | |
|---|
| 1092 | | - if (dwc->revision >= DWC3_REVISION_250A) { |
|---|
| 1077 | + if (!DWC3_VER_IS_PRIOR(DWC3, 250A)) { |
|---|
| 1093 | 1078 | reg = dwc3_readl(dwc->regs, DWC3_GUCTL1); |
|---|
| 1094 | 1079 | |
|---|
| 1095 | 1080 | /* |
|---|
| 1096 | 1081 | * Enable hardware control of sending remote wakeup |
|---|
| 1097 | 1082 | * in HS when the device is in the L1 state. |
|---|
| 1098 | 1083 | */ |
|---|
| 1099 | | - if (dwc->revision >= DWC3_REVISION_290A) |
|---|
| 1084 | + if (!DWC3_VER_IS_PRIOR(DWC3, 290A)) |
|---|
| 1100 | 1085 | reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW; |
|---|
| 1086 | + |
|---|
| 1087 | + /* |
|---|
| 1088 | + * Decouple USB 2.0 L1 & L2 events which will allow for |
|---|
| 1089 | + * gadget driver to only receive U3/L2 suspend & wakeup |
|---|
| 1090 | + * events and prevent the more frequent L1 LPM transitions |
|---|
| 1091 | + * from interrupting the driver. |
|---|
| 1092 | + */ |
|---|
| 1093 | + if (!DWC3_VER_IS_PRIOR(DWC3, 300A)) |
|---|
| 1094 | + reg |= DWC3_GUCTL1_DEV_DECOUPLE_L1L2_EVT; |
|---|
| 1101 | 1095 | |
|---|
| 1102 | 1096 | if (dwc->dis_tx_ipgap_linecheck_quirk) |
|---|
| 1103 | 1097 | reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS; |
|---|
| .. | .. |
|---|
| 1132 | 1126 | * Must config both number of packets and max burst settings to enable |
|---|
| 1133 | 1127 | * RX and/or TX threshold. |
|---|
| 1134 | 1128 | */ |
|---|
| 1135 | | - if (dwc3_is_usb31(dwc) && dwc->dr_mode == USB_DR_MODE_HOST) { |
|---|
| 1129 | + if (!DWC3_IP_IS(DWC3) && dwc->dr_mode == USB_DR_MODE_HOST) { |
|---|
| 1136 | 1130 | u8 rx_thr_num = dwc->rx_thr_num_pkt_prd; |
|---|
| 1137 | 1131 | u8 rx_maxburst = dwc->rx_max_burst_prd; |
|---|
| 1138 | 1132 | u8 tx_thr_num = dwc->tx_thr_num_pkt_prd; |
|---|
| .. | .. |
|---|
| 1206 | 1200 | |
|---|
| 1207 | 1201 | if (IS_ERR(dwc->usb2_phy)) { |
|---|
| 1208 | 1202 | ret = PTR_ERR(dwc->usb2_phy); |
|---|
| 1209 | | - if (ret == -ENXIO || ret == -ENODEV) { |
|---|
| 1203 | + if (ret == -ENXIO || ret == -ENODEV) |
|---|
| 1210 | 1204 | 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 | | - } |
|---|
| 1205 | + else |
|---|
| 1206 | + return dev_err_probe(dev, ret, "no usb2 phy configured\n"); |
|---|
| 1217 | 1207 | } |
|---|
| 1218 | 1208 | |
|---|
| 1219 | 1209 | if (IS_ERR(dwc->usb3_phy)) { |
|---|
| 1220 | 1210 | ret = PTR_ERR(dwc->usb3_phy); |
|---|
| 1221 | | - if (ret == -ENXIO || ret == -ENODEV) { |
|---|
| 1211 | + if (ret == -ENXIO || ret == -ENODEV) |
|---|
| 1222 | 1212 | 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 | | - } |
|---|
| 1213 | + else |
|---|
| 1214 | + return dev_err_probe(dev, ret, "no usb3 phy configured\n"); |
|---|
| 1229 | 1215 | } |
|---|
| 1230 | 1216 | |
|---|
| 1231 | 1217 | dwc->usb2_generic_phy = devm_phy_get(dev, "usb2-phy"); |
|---|
| 1232 | 1218 | if (IS_ERR(dwc->usb2_generic_phy)) { |
|---|
| 1233 | 1219 | ret = PTR_ERR(dwc->usb2_generic_phy); |
|---|
| 1234 | | - if (ret == -ENOSYS || ret == -ENODEV) { |
|---|
| 1220 | + if (ret == -ENOSYS || ret == -ENODEV) |
|---|
| 1235 | 1221 | 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 | | - } |
|---|
| 1222 | + else |
|---|
| 1223 | + return dev_err_probe(dev, ret, "no usb2 phy configured\n"); |
|---|
| 1242 | 1224 | } |
|---|
| 1243 | 1225 | |
|---|
| 1244 | 1226 | dwc->usb3_generic_phy = devm_phy_get(dev, "usb3-phy"); |
|---|
| 1245 | 1227 | if (IS_ERR(dwc->usb3_generic_phy)) { |
|---|
| 1246 | 1228 | ret = PTR_ERR(dwc->usb3_generic_phy); |
|---|
| 1247 | | - if (ret == -ENOSYS || ret == -ENODEV) { |
|---|
| 1229 | + if (ret == -ENOSYS || ret == -ENODEV) |
|---|
| 1248 | 1230 | 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 | | - } |
|---|
| 1231 | + else |
|---|
| 1232 | + return dev_err_probe(dev, ret, "no usb3 phy configured\n"); |
|---|
| 1255 | 1233 | } |
|---|
| 1256 | 1234 | |
|---|
| 1257 | 1235 | return 0; |
|---|
| .. | .. |
|---|
| 1272 | 1250 | phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_DEVICE); |
|---|
| 1273 | 1251 | |
|---|
| 1274 | 1252 | 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); |
|---|
| 1253 | + if (ret) |
|---|
| 1254 | + return dev_err_probe(dev, ret, "failed to initialize gadget\n"); |
|---|
| 1283 | 1255 | break; |
|---|
| 1284 | 1256 | 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 | 1257 | dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST); |
|---|
| 1298 | 1258 | |
|---|
| 1299 | 1259 | if (dwc->usb2_phy) |
|---|
| .. | .. |
|---|
| 1302 | 1262 | phy_set_mode(dwc->usb3_generic_phy, PHY_MODE_USB_HOST); |
|---|
| 1303 | 1263 | |
|---|
| 1304 | 1264 | 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); |
|---|
| 1265 | + if (ret) |
|---|
| 1266 | + return dev_err_probe(dev, ret, "failed to initialize host\n"); |
|---|
| 1313 | 1267 | break; |
|---|
| 1314 | 1268 | case USB_DR_MODE_OTG: |
|---|
| 1315 | 1269 | 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 | 1270 | 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); |
|---|
| 1271 | + if (ret) |
|---|
| 1272 | + return dev_err_probe(dev, ret, "failed to initialize dual-role\n"); |
|---|
| 1336 | 1273 | break; |
|---|
| 1337 | 1274 | default: |
|---|
| 1338 | 1275 | dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode); |
|---|
| .. | .. |
|---|
| 1369 | 1306 | u8 lpm_nyet_threshold; |
|---|
| 1370 | 1307 | u8 tx_de_emphasis; |
|---|
| 1371 | 1308 | 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; |
|---|
| 1309 | + u8 rx_thr_num_pkt_prd = 0; |
|---|
| 1310 | + u8 rx_max_burst_prd = 0; |
|---|
| 1311 | + u8 tx_thr_num_pkt_prd = 0; |
|---|
| 1312 | + u8 tx_max_burst_prd = 0; |
|---|
| 1313 | + u8 tx_fifo_resize_max_num; |
|---|
| 1314 | + const char *usb_psy_name; |
|---|
| 1315 | + int ret; |
|---|
| 1376 | 1316 | |
|---|
| 1377 | 1317 | /* default to highest possible threshold */ |
|---|
| 1378 | 1318 | lpm_nyet_threshold = 0xf; |
|---|
| .. | .. |
|---|
| 1386 | 1326 | */ |
|---|
| 1387 | 1327 | hird_threshold = 12; |
|---|
| 1388 | 1328 | |
|---|
| 1329 | + /* |
|---|
| 1330 | + * default to a TXFIFO size large enough to fit 6 max packets. This |
|---|
| 1331 | + * allows for systems with larger bus latencies to have some headroom |
|---|
| 1332 | + * for endpoints that have a large bMaxBurst value. |
|---|
| 1333 | + */ |
|---|
| 1334 | + tx_fifo_resize_max_num = 6; |
|---|
| 1335 | + |
|---|
| 1389 | 1336 | dwc->maximum_speed = usb_get_maximum_speed(dev); |
|---|
| 1337 | + dwc->max_ssp_rate = usb_get_maximum_ssp_rate(dev); |
|---|
| 1390 | 1338 | dwc->dr_mode = usb_get_dr_mode(dev); |
|---|
| 1391 | 1339 | dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node); |
|---|
| 1392 | 1340 | |
|---|
| .. | .. |
|---|
| 1396 | 1344 | dwc->sysdev = dwc->dev->parent; |
|---|
| 1397 | 1345 | else |
|---|
| 1398 | 1346 | dwc->sysdev = dwc->dev; |
|---|
| 1347 | + |
|---|
| 1348 | + ret = device_property_read_string(dev, "usb-psy-name", &usb_psy_name); |
|---|
| 1349 | + if (ret >= 0) { |
|---|
| 1350 | + dwc->usb_psy = power_supply_get_by_name(usb_psy_name); |
|---|
| 1351 | + if (!dwc->usb_psy) |
|---|
| 1352 | + dev_err(dev, "couldn't get usb power supply\n"); |
|---|
| 1353 | + } |
|---|
| 1399 | 1354 | |
|---|
| 1400 | 1355 | dwc->has_lpm_erratum = device_property_read_bool(dev, |
|---|
| 1401 | 1356 | "snps,has-lpm-erratum"); |
|---|
| .. | .. |
|---|
| 1411 | 1366 | "snps,usb3_lpm_capable"); |
|---|
| 1412 | 1367 | dwc->usb2_lpm_disable = device_property_read_bool(dev, |
|---|
| 1413 | 1368 | "snps,usb2-lpm-disable"); |
|---|
| 1369 | + dwc->usb2_gadget_lpm_disable = device_property_read_bool(dev, |
|---|
| 1370 | + "snps,usb2-gadget-lpm-disable"); |
|---|
| 1414 | 1371 | device_property_read_u8(dev, "snps,rx-thr-num-pkt-prd", |
|---|
| 1415 | 1372 | &rx_thr_num_pkt_prd); |
|---|
| 1416 | 1373 | device_property_read_u8(dev, "snps,rx-max-burst-prd", |
|---|
| .. | .. |
|---|
| 1419 | 1376 | &tx_thr_num_pkt_prd); |
|---|
| 1420 | 1377 | device_property_read_u8(dev, "snps,tx-max-burst-prd", |
|---|
| 1421 | 1378 | &tx_max_burst_prd); |
|---|
| 1379 | + dwc->do_fifo_resize = device_property_read_bool(dev, |
|---|
| 1380 | + "tx-fifo-resize"); |
|---|
| 1381 | + if (dwc->do_fifo_resize) |
|---|
| 1382 | + device_property_read_u8(dev, "tx-fifo-max-num", |
|---|
| 1383 | + &tx_fifo_resize_max_num); |
|---|
| 1422 | 1384 | |
|---|
| 1423 | 1385 | dwc->disable_scramble_quirk = device_property_read_bool(dev, |
|---|
| 1424 | 1386 | "snps,disable_scramble_quirk"); |
|---|
| .. | .. |
|---|
| 1440 | 1402 | "snps,dis_u3_susphy_quirk"); |
|---|
| 1441 | 1403 | dwc->dis_u2_susphy_quirk = device_property_read_bool(dev, |
|---|
| 1442 | 1404 | "snps,dis_u2_susphy_quirk"); |
|---|
| 1443 | | - dwc->dis_u1u2_quirk = device_property_read_bool(dev, |
|---|
| 1444 | | - "snps,dis-u1u2-quirk"); |
|---|
| 1445 | 1405 | dwc->dis_enblslpm_quirk = device_property_read_bool(dev, |
|---|
| 1446 | 1406 | "snps,dis_enblslpm_quirk"); |
|---|
| 1407 | + dwc->dis_u1_entry_quirk = device_property_read_bool(dev, |
|---|
| 1408 | + "snps,dis-u1-entry-quirk"); |
|---|
| 1409 | + dwc->dis_u2_entry_quirk = device_property_read_bool(dev, |
|---|
| 1410 | + "snps,dis-u2-entry-quirk"); |
|---|
| 1447 | 1411 | dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev, |
|---|
| 1448 | 1412 | "snps,dis_rxdet_inp3_quirk"); |
|---|
| 1449 | 1413 | dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev, |
|---|
| .. | .. |
|---|
| 1454 | 1418 | "snps,dis-tx-ipgap-linecheck-quirk"); |
|---|
| 1455 | 1419 | dwc->parkmode_disable_ss_quirk = device_property_read_bool(dev, |
|---|
| 1456 | 1420 | "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"); |
|---|
| 1463 | 1421 | |
|---|
| 1464 | 1422 | dwc->tx_de_emphasis_quirk = device_property_read_bool(dev, |
|---|
| 1465 | 1423 | "snps,tx_de_emphasis_quirk"); |
|---|
| .. | .. |
|---|
| 1472 | 1430 | |
|---|
| 1473 | 1431 | dwc->dis_metastability_quirk = device_property_read_bool(dev, |
|---|
| 1474 | 1432 | "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"); |
|---|
| 1433 | + |
|---|
| 1434 | + dwc->dis_split_quirk = device_property_read_bool(dev, |
|---|
| 1435 | + "snps,dis-split-quirk"); |
|---|
| 1481 | 1436 | |
|---|
| 1482 | 1437 | dwc->lpm_nyet_threshold = lpm_nyet_threshold; |
|---|
| 1483 | 1438 | dwc->tx_de_emphasis = tx_de_emphasis; |
|---|
| 1484 | 1439 | |
|---|
| 1485 | | - dwc->hird_threshold = hird_threshold |
|---|
| 1486 | | - | (dwc->is_utmi_l1_suspend << 4); |
|---|
| 1440 | + dwc->hird_threshold = hird_threshold; |
|---|
| 1487 | 1441 | |
|---|
| 1488 | 1442 | dwc->rx_thr_num_pkt_prd = rx_thr_num_pkt_prd; |
|---|
| 1489 | 1443 | dwc->rx_max_burst_prd = rx_max_burst_prd; |
|---|
| .. | .. |
|---|
| 1492 | 1446 | dwc->tx_max_burst_prd = tx_max_burst_prd; |
|---|
| 1493 | 1447 | |
|---|
| 1494 | 1448 | dwc->imod_interval = 0; |
|---|
| 1449 | + |
|---|
| 1450 | + dwc->tx_fifo_resize_max_num = tx_fifo_resize_max_num; |
|---|
| 1495 | 1451 | } |
|---|
| 1496 | 1452 | |
|---|
| 1497 | 1453 | /* check whether the core supports IMOD */ |
|---|
| 1498 | 1454 | bool dwc3_has_imod(struct dwc3 *dwc) |
|---|
| 1499 | 1455 | { |
|---|
| 1500 | | - return ((dwc3_is_usb3(dwc) && |
|---|
| 1501 | | - dwc->revision >= DWC3_REVISION_300A) || |
|---|
| 1502 | | - (dwc3_is_usb31(dwc) && |
|---|
| 1503 | | - dwc->revision >= DWC3_USB31_REVISION_120A)); |
|---|
| 1456 | + return DWC3_VER_IS_WITHIN(DWC3, 300A, ANY) || |
|---|
| 1457 | + DWC3_VER_IS_WITHIN(DWC31, 120A, ANY) || |
|---|
| 1458 | + DWC3_IP_IS(DWC32); |
|---|
| 1504 | 1459 | } |
|---|
| 1505 | 1460 | |
|---|
| 1506 | 1461 | static void dwc3_check_params(struct dwc3 *dwc) |
|---|
| 1507 | 1462 | { |
|---|
| 1508 | 1463 | struct device *dev = dwc->dev; |
|---|
| 1464 | + unsigned int hwparam_gen = |
|---|
| 1465 | + DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3); |
|---|
| 1509 | 1466 | |
|---|
| 1510 | 1467 | /* Check for proper value of imod_interval */ |
|---|
| 1511 | 1468 | if (dwc->imod_interval && !dwc3_has_imod(dwc)) { |
|---|
| .. | .. |
|---|
| 1521 | 1478 | * affected version. |
|---|
| 1522 | 1479 | */ |
|---|
| 1523 | 1480 | if (!dwc->imod_interval && |
|---|
| 1524 | | - (dwc->revision == DWC3_REVISION_300A)) |
|---|
| 1481 | + DWC3_VER_IS(DWC3, 300A)) |
|---|
| 1525 | 1482 | dwc->imod_interval = 1; |
|---|
| 1526 | 1483 | |
|---|
| 1527 | 1484 | /* Check the maximum_speed parameter */ |
|---|
| .. | .. |
|---|
| 1529 | 1486 | case USB_SPEED_LOW: |
|---|
| 1530 | 1487 | case USB_SPEED_FULL: |
|---|
| 1531 | 1488 | case USB_SPEED_HIGH: |
|---|
| 1489 | + break; |
|---|
| 1532 | 1490 | case USB_SPEED_SUPER: |
|---|
| 1491 | + if (hwparam_gen == DWC3_GHWPARAMS3_SSPHY_IFC_DIS) |
|---|
| 1492 | + dev_warn(dev, "UDC doesn't support Gen 1\n"); |
|---|
| 1493 | + break; |
|---|
| 1533 | 1494 | case USB_SPEED_SUPER_PLUS: |
|---|
| 1495 | + if ((DWC3_IP_IS(DWC32) && |
|---|
| 1496 | + hwparam_gen == DWC3_GHWPARAMS3_SSPHY_IFC_DIS) || |
|---|
| 1497 | + (!DWC3_IP_IS(DWC32) && |
|---|
| 1498 | + hwparam_gen != DWC3_GHWPARAMS3_SSPHY_IFC_GEN2)) |
|---|
| 1499 | + dev_warn(dev, "UDC doesn't support SSP\n"); |
|---|
| 1534 | 1500 | break; |
|---|
| 1535 | 1501 | default: |
|---|
| 1536 | 1502 | dev_err(dev, "invalid maximum_speed parameter %d\n", |
|---|
| 1537 | 1503 | dwc->maximum_speed); |
|---|
| 1538 | | - /* fall through */ |
|---|
| 1504 | + fallthrough; |
|---|
| 1539 | 1505 | 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)) |
|---|
| 1506 | + switch (hwparam_gen) { |
|---|
| 1507 | + case DWC3_GHWPARAMS3_SSPHY_IFC_GEN2: |
|---|
| 1549 | 1508 | dwc->maximum_speed = USB_SPEED_SUPER_PLUS; |
|---|
| 1550 | | - |
|---|
| 1509 | + break; |
|---|
| 1510 | + case DWC3_GHWPARAMS3_SSPHY_IFC_GEN1: |
|---|
| 1511 | + if (DWC3_IP_IS(DWC32)) |
|---|
| 1512 | + dwc->maximum_speed = USB_SPEED_SUPER_PLUS; |
|---|
| 1513 | + else |
|---|
| 1514 | + dwc->maximum_speed = USB_SPEED_SUPER; |
|---|
| 1515 | + break; |
|---|
| 1516 | + case DWC3_GHWPARAMS3_SSPHY_IFC_DIS: |
|---|
| 1517 | + dwc->maximum_speed = USB_SPEED_HIGH; |
|---|
| 1518 | + break; |
|---|
| 1519 | + default: |
|---|
| 1520 | + dwc->maximum_speed = USB_SPEED_SUPER; |
|---|
| 1521 | + break; |
|---|
| 1522 | + } |
|---|
| 1551 | 1523 | break; |
|---|
| 1552 | 1524 | } |
|---|
| 1553 | | -} |
|---|
| 1554 | 1525 | |
|---|
| 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; |
|---|
| 1526 | + /* |
|---|
| 1527 | + * Currently the controller does not have visibility into the HW |
|---|
| 1528 | + * parameter to determine the maximum number of lanes the HW supports. |
|---|
| 1529 | + * If the number of lanes is not specified in the device property, then |
|---|
| 1530 | + * set the default to support dual-lane for DWC_usb32 and single-lane |
|---|
| 1531 | + * for DWC_usb31 for super-speed-plus. |
|---|
| 1532 | + */ |
|---|
| 1533 | + if (dwc->maximum_speed == USB_SPEED_SUPER_PLUS) { |
|---|
| 1534 | + switch (dwc->max_ssp_rate) { |
|---|
| 1535 | + case USB_SSP_GEN_2x1: |
|---|
| 1536 | + if (hwparam_gen == DWC3_GHWPARAMS3_SSPHY_IFC_GEN1) |
|---|
| 1537 | + dev_warn(dev, "UDC only supports Gen 1\n"); |
|---|
| 1538 | + break; |
|---|
| 1539 | + case USB_SSP_GEN_1x2: |
|---|
| 1540 | + case USB_SSP_GEN_2x2: |
|---|
| 1541 | + if (DWC3_IP_IS(DWC31)) |
|---|
| 1542 | + dev_warn(dev, "UDC only supports single lane\n"); |
|---|
| 1543 | + break; |
|---|
| 1544 | + case USB_SSP_GEN_UNKNOWN: |
|---|
| 1545 | + default: |
|---|
| 1546 | + switch (hwparam_gen) { |
|---|
| 1547 | + case DWC3_GHWPARAMS3_SSPHY_IFC_GEN2: |
|---|
| 1548 | + if (DWC3_IP_IS(DWC32)) |
|---|
| 1549 | + dwc->max_ssp_rate = USB_SSP_GEN_2x2; |
|---|
| 1550 | + else |
|---|
| 1551 | + dwc->max_ssp_rate = USB_SSP_GEN_2x1; |
|---|
| 1552 | + break; |
|---|
| 1553 | + case DWC3_GHWPARAMS3_SSPHY_IFC_GEN1: |
|---|
| 1554 | + if (DWC3_IP_IS(DWC32)) |
|---|
| 1555 | + dwc->max_ssp_rate = USB_SSP_GEN_1x2; |
|---|
| 1556 | + break; |
|---|
| 1557 | + } |
|---|
| 1558 | + break; |
|---|
| 1559 | + } |
|---|
| 1567 | 1560 | } |
|---|
| 1568 | | - |
|---|
| 1569 | | - pm_runtime_put_sync_suspend(dev); |
|---|
| 1570 | 1561 | } |
|---|
| 1571 | 1562 | |
|---|
| 1572 | 1563 | static int dwc3_probe(struct platform_device *pdev) |
|---|
| 1573 | 1564 | { |
|---|
| 1574 | 1565 | struct device *dev = &pdev->dev; |
|---|
| 1575 | 1566 | struct resource *res, dwc_res; |
|---|
| 1567 | + struct dwc3_vendor *vdwc; |
|---|
| 1576 | 1568 | struct dwc3 *dwc; |
|---|
| 1577 | 1569 | |
|---|
| 1578 | 1570 | int ret; |
|---|
| 1579 | 1571 | |
|---|
| 1580 | 1572 | void __iomem *regs; |
|---|
| 1581 | 1573 | |
|---|
| 1582 | | - dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL); |
|---|
| 1583 | | - if (!dwc) |
|---|
| 1574 | + vdwc = devm_kzalloc(dev, sizeof(*vdwc), GFP_KERNEL); |
|---|
| 1575 | + if (!vdwc) |
|---|
| 1584 | 1576 | 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; |
|---|
| 1577 | + dwc = &vdwc->dwc; |
|---|
| 1590 | 1578 | |
|---|
| 1591 | 1579 | dwc->dev = dev; |
|---|
| 1592 | 1580 | |
|---|
| .. | .. |
|---|
| 1616 | 1604 | dwc->regs = regs; |
|---|
| 1617 | 1605 | dwc->regs_size = resource_size(&dwc_res); |
|---|
| 1618 | 1606 | |
|---|
| 1619 | | - dwc->reset = devm_reset_control_get_optional_shared(dev, NULL); |
|---|
| 1607 | + dwc3_get_properties(dwc); |
|---|
| 1608 | + |
|---|
| 1609 | + dwc->reset = devm_reset_control_array_get_optional_shared(dev); |
|---|
| 1620 | 1610 | if (IS_ERR(dwc->reset)) |
|---|
| 1621 | 1611 | return PTR_ERR(dwc->reset); |
|---|
| 1622 | 1612 | |
|---|
| 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 | 1613 | 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); |
|---|
| 1614 | + ret = devm_clk_bulk_get_all(dev, &dwc->clks); |
|---|
| 1649 | 1615 | if (ret == -EPROBE_DEFER) |
|---|
| 1650 | | - goto assert_reset; |
|---|
| 1616 | + return ret; |
|---|
| 1651 | 1617 | /* |
|---|
| 1652 | 1618 | * Clocks are optional, but new DT platforms should support all |
|---|
| 1653 | 1619 | * clocks as required by the DT-binding. |
|---|
| 1654 | 1620 | */ |
|---|
| 1655 | | - if (ret) |
|---|
| 1621 | + if (ret < 0) |
|---|
| 1656 | 1622 | dwc->num_clks = 0; |
|---|
| 1623 | + else |
|---|
| 1624 | + dwc->num_clks = ret; |
|---|
| 1625 | + |
|---|
| 1657 | 1626 | } |
|---|
| 1658 | 1627 | |
|---|
| 1659 | | - ret = clk_bulk_prepare(dwc->num_clks, dwc->clks); |
|---|
| 1628 | + ret = reset_control_deassert(dwc->reset); |
|---|
| 1660 | 1629 | if (ret) |
|---|
| 1661 | | - goto put_clks; |
|---|
| 1630 | + return ret; |
|---|
| 1662 | 1631 | |
|---|
| 1663 | | - ret = clk_bulk_enable(dwc->num_clks, dwc->clks); |
|---|
| 1632 | + ret = clk_bulk_prepare_enable(dwc->num_clks, dwc->clks); |
|---|
| 1664 | 1633 | if (ret) |
|---|
| 1665 | | - goto unprepare_clks; |
|---|
| 1634 | + goto assert_reset; |
|---|
| 1635 | + |
|---|
| 1636 | + if (!dwc3_core_is_valid(dwc)) { |
|---|
| 1637 | + dev_err(dwc->dev, "this is not a DesignWare USB3 DRD Core\n"); |
|---|
| 1638 | + ret = -ENODEV; |
|---|
| 1639 | + goto disable_clks; |
|---|
| 1640 | + } |
|---|
| 1666 | 1641 | |
|---|
| 1667 | 1642 | platform_set_drvdata(pdev, dwc); |
|---|
| 1668 | 1643 | dwc3_cache_hwparams(dwc); |
|---|
| 1669 | 1644 | |
|---|
| 1670 | 1645 | spin_lock_init(&dwc->lock); |
|---|
| 1646 | + mutex_init(&dwc->mutex); |
|---|
| 1671 | 1647 | |
|---|
| 1672 | 1648 | pm_runtime_set_active(dev); |
|---|
| 1673 | 1649 | pm_runtime_use_autosuspend(dev); |
|---|
| .. | .. |
|---|
| 1690 | 1666 | if (ret) |
|---|
| 1691 | 1667 | goto err3; |
|---|
| 1692 | 1668 | |
|---|
| 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 | 1669 | ret = dwc3_alloc_scratch_buffers(dwc); |
|---|
| 1701 | 1670 | if (ret) |
|---|
| 1702 | 1671 | goto err3; |
|---|
| 1703 | 1672 | |
|---|
| 1704 | 1673 | ret = dwc3_core_init(dwc); |
|---|
| 1705 | 1674 | if (ret) { |
|---|
| 1706 | | - if (ret != -EPROBE_DEFER) |
|---|
| 1707 | | - dev_err(dev, "failed to initialize core: %d\n", ret); |
|---|
| 1675 | + dev_err_probe(dev, ret, "failed to initialize core\n"); |
|---|
| 1708 | 1676 | goto err4; |
|---|
| 1709 | 1677 | } |
|---|
| 1710 | 1678 | |
|---|
| .. | .. |
|---|
| 1715 | 1683 | if (ret) |
|---|
| 1716 | 1684 | goto err5; |
|---|
| 1717 | 1685 | |
|---|
| 1718 | | - if (dwc->en_runtime) |
|---|
| 1719 | | - async_schedule(dwc3_rockchip_async_probe, dwc); |
|---|
| 1720 | | - else |
|---|
| 1686 | + if (dwc->dr_mode == USB_DR_MODE_OTG && |
|---|
| 1687 | + of_device_is_compatible(dev->parent->of_node, |
|---|
| 1688 | + "rockchip,rk3399-dwc3")) { |
|---|
| 1689 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
|---|
| 1690 | + pm_runtime_set_autosuspend_delay(dev, 100); |
|---|
| 1691 | +#endif |
|---|
| 1692 | + pm_runtime_allow(dev); |
|---|
| 1693 | + pm_runtime_put_sync_suspend(dev); |
|---|
| 1694 | + } else { |
|---|
| 1721 | 1695 | pm_runtime_put(dev); |
|---|
| 1696 | + } |
|---|
| 1722 | 1697 | |
|---|
| 1723 | 1698 | return 0; |
|---|
| 1724 | 1699 | |
|---|
| .. | .. |
|---|
| 1726 | 1701 | dwc3_debugfs_exit(dwc); |
|---|
| 1727 | 1702 | dwc3_event_buffers_cleanup(dwc); |
|---|
| 1728 | 1703 | |
|---|
| 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 | 1704 | usb_phy_set_suspend(dwc->usb2_phy, 1); |
|---|
| 1735 | 1705 | usb_phy_set_suspend(dwc->usb3_phy, 1); |
|---|
| 1736 | 1706 | phy_power_off(dwc->usb2_generic_phy); |
|---|
| 1737 | 1707 | phy_power_off(dwc->usb3_generic_phy); |
|---|
| 1708 | + |
|---|
| 1709 | + usb_phy_shutdown(dwc->usb2_phy); |
|---|
| 1710 | + usb_phy_shutdown(dwc->usb3_phy); |
|---|
| 1711 | + phy_exit(dwc->usb2_generic_phy); |
|---|
| 1712 | + phy_exit(dwc->usb3_generic_phy); |
|---|
| 1738 | 1713 | |
|---|
| 1739 | 1714 | dwc3_ulpi_exit(dwc); |
|---|
| 1740 | 1715 | |
|---|
| .. | .. |
|---|
| 1751 | 1726 | pm_runtime_put_sync(&pdev->dev); |
|---|
| 1752 | 1727 | pm_runtime_disable(&pdev->dev); |
|---|
| 1753 | 1728 | |
|---|
| 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); |
|---|
| 1729 | +disable_clks: |
|---|
| 1730 | + clk_bulk_disable_unprepare(dwc->num_clks, dwc->clks); |
|---|
| 1759 | 1731 | assert_reset: |
|---|
| 1760 | 1732 | reset_control_assert(dwc->reset); |
|---|
| 1733 | + |
|---|
| 1734 | + if (dwc->usb_psy) |
|---|
| 1735 | + power_supply_put(dwc->usb_psy); |
|---|
| 1761 | 1736 | |
|---|
| 1762 | 1737 | return ret; |
|---|
| 1763 | 1738 | } |
|---|
| .. | .. |
|---|
| 1780 | 1755 | |
|---|
| 1781 | 1756 | dwc3_free_event_buffers(dwc); |
|---|
| 1782 | 1757 | dwc3_free_scratch_buffers(dwc); |
|---|
| 1783 | | - clk_bulk_put(dwc->num_clks, dwc->clks); |
|---|
| 1758 | + |
|---|
| 1759 | + if (dwc->usb_psy) |
|---|
| 1760 | + power_supply_put(dwc->usb_psy); |
|---|
| 1784 | 1761 | |
|---|
| 1785 | 1762 | return 0; |
|---|
| 1786 | 1763 | } |
|---|
| .. | .. |
|---|
| 1790 | 1767 | { |
|---|
| 1791 | 1768 | int ret; |
|---|
| 1792 | 1769 | |
|---|
| 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 | | - } |
|---|
| 1770 | + ret = reset_control_deassert(dwc->reset); |
|---|
| 1771 | + if (ret) |
|---|
| 1772 | + return ret; |
|---|
| 1798 | 1773 | |
|---|
| 1799 | | - ret = clk_bulk_prepare(dwc->num_clks, dwc->clks); |
|---|
| 1774 | + ret = clk_bulk_prepare_enable(dwc->num_clks, dwc->clks); |
|---|
| 1800 | 1775 | if (ret) |
|---|
| 1801 | 1776 | goto assert_reset; |
|---|
| 1802 | | - |
|---|
| 1803 | | - ret = clk_bulk_enable(dwc->num_clks, dwc->clks); |
|---|
| 1804 | | - if (ret) |
|---|
| 1805 | | - goto unprepare_clks; |
|---|
| 1806 | 1777 | |
|---|
| 1807 | 1778 | ret = dwc3_core_init(dwc); |
|---|
| 1808 | 1779 | if (ret) |
|---|
| .. | .. |
|---|
| 1811 | 1782 | return 0; |
|---|
| 1812 | 1783 | |
|---|
| 1813 | 1784 | disable_clks: |
|---|
| 1814 | | - clk_bulk_disable(dwc->num_clks, dwc->clks); |
|---|
| 1815 | | -unprepare_clks: |
|---|
| 1816 | | - clk_bulk_unprepare(dwc->num_clks, dwc->clks); |
|---|
| 1785 | + clk_bulk_disable_unprepare(dwc->num_clks, dwc->clks); |
|---|
| 1817 | 1786 | assert_reset: |
|---|
| 1818 | | - if (!dwc->drd_connected && dwc->dr_mode == USB_DR_MODE_OTG) |
|---|
| 1819 | | - reset_control_assert(dwc->reset); |
|---|
| 1787 | + reset_control_assert(dwc->reset); |
|---|
| 1820 | 1788 | |
|---|
| 1821 | 1789 | return ret; |
|---|
| 1822 | 1790 | } |
|---|
| .. | .. |
|---|
| 1828 | 1796 | |
|---|
| 1829 | 1797 | switch (dwc->current_dr_role) { |
|---|
| 1830 | 1798 | case DWC3_GCTL_PRTCAP_DEVICE: |
|---|
| 1831 | | - spin_lock_irqsave(&dwc->lock, flags); |
|---|
| 1799 | + if (pm_runtime_suspended(dwc->dev)) |
|---|
| 1800 | + break; |
|---|
| 1832 | 1801 | dwc3_gadget_suspend(dwc); |
|---|
| 1833 | | - spin_unlock_irqrestore(&dwc->lock, flags); |
|---|
| 1834 | 1802 | synchronize_irq(dwc->irq_gadget); |
|---|
| 1835 | 1803 | dwc3_core_exit(dwc); |
|---|
| 1836 | 1804 | break; |
|---|
| 1837 | 1805 | case DWC3_GCTL_PRTCAP_HOST: |
|---|
| 1838 | | - if (!PMSG_IS_AUTO(msg) || dwc->en_runtime) { |
|---|
| 1806 | + if (!PMSG_IS_AUTO(msg)) { |
|---|
| 1839 | 1807 | dwc3_core_exit(dwc); |
|---|
| 1840 | 1808 | break; |
|---|
| 1841 | 1809 | } |
|---|
| .. | .. |
|---|
| 1871 | 1839 | dwc3_core_exit(dwc); |
|---|
| 1872 | 1840 | break; |
|---|
| 1873 | 1841 | default: |
|---|
| 1874 | | - /* do nothing */ |
|---|
| 1842 | + if (!pm_runtime_suspended(dwc->dev)) |
|---|
| 1843 | + dwc3_core_exit(dwc); |
|---|
| 1875 | 1844 | break; |
|---|
| 1876 | 1845 | } |
|---|
| 1877 | 1846 | |
|---|
| .. | .. |
|---|
| 1891 | 1860 | return ret; |
|---|
| 1892 | 1861 | |
|---|
| 1893 | 1862 | dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE); |
|---|
| 1894 | | - spin_lock_irqsave(&dwc->lock, flags); |
|---|
| 1895 | 1863 | dwc3_gadget_resume(dwc); |
|---|
| 1896 | | - spin_unlock_irqrestore(&dwc->lock, flags); |
|---|
| 1897 | 1864 | break; |
|---|
| 1898 | 1865 | case DWC3_GCTL_PRTCAP_HOST: |
|---|
| 1899 | | - if (!PMSG_IS_AUTO(msg) || dwc->en_runtime) { |
|---|
| 1866 | + if (!PMSG_IS_AUTO(msg)) { |
|---|
| 1900 | 1867 | ret = dwc3_core_init_for_resume(dwc); |
|---|
| 1901 | 1868 | if (ret) |
|---|
| 1902 | 1869 | return ret; |
|---|
| .. | .. |
|---|
| 1938 | 1905 | |
|---|
| 1939 | 1906 | break; |
|---|
| 1940 | 1907 | default: |
|---|
| 1941 | | - /* do nothing */ |
|---|
| 1908 | + ret = dwc3_core_init_for_resume(dwc); |
|---|
| 1909 | + if (ret) |
|---|
| 1910 | + return ret; |
|---|
| 1942 | 1911 | break; |
|---|
| 1943 | 1912 | } |
|---|
| 1944 | 1913 | |
|---|
| .. | .. |
|---|
| 2032 | 2001 | struct dwc3 *dwc = dev_get_drvdata(dev); |
|---|
| 2033 | 2002 | int ret; |
|---|
| 2034 | 2003 | |
|---|
| 2035 | | - if (dwc->uwk_en) { |
|---|
| 2036 | | - dwc3_gadget_disable_irq(dwc); |
|---|
| 2037 | | - synchronize_irq(dwc->irq_gadget); |
|---|
| 2038 | | - return 0; |
|---|
| 2039 | | - } |
|---|
| 2040 | | - |
|---|
| 2041 | 2004 | if (pm_runtime_suspended(dwc->dev)) |
|---|
| 2042 | 2005 | return 0; |
|---|
| 2043 | 2006 | |
|---|
| 2044 | 2007 | ret = dwc3_suspend_common(dwc, PMSG_SUSPEND); |
|---|
| 2045 | 2008 | if (ret) |
|---|
| 2046 | 2009 | 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 | 2010 | |
|---|
| 2070 | 2011 | pinctrl_pm_select_sleep_state(dev); |
|---|
| 2071 | 2012 | |
|---|
| .. | .. |
|---|
| 2077 | 2018 | struct dwc3 *dwc = dev_get_drvdata(dev); |
|---|
| 2078 | 2019 | int ret; |
|---|
| 2079 | 2020 | |
|---|
| 2080 | | - if (dwc->uwk_en) { |
|---|
| 2081 | | - dwc3_gadget_enable_irq(dwc); |
|---|
| 2082 | | - return 0; |
|---|
| 2083 | | - } |
|---|
| 2084 | | - |
|---|
| 2085 | 2021 | if (pm_runtime_suspended(dwc->dev)) |
|---|
| 2086 | 2022 | return 0; |
|---|
| 2087 | 2023 | |
|---|
| 2088 | 2024 | 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 | 2025 | |
|---|
| 2094 | 2026 | ret = dwc3_resume_common(dwc, PMSG_RESUME); |
|---|
| 2095 | 2027 | if (ret) |
|---|
| .. | .. |
|---|
| 2101 | 2033 | |
|---|
| 2102 | 2034 | return 0; |
|---|
| 2103 | 2035 | } |
|---|
| 2036 | + |
|---|
| 2037 | +static void dwc3_complete(struct device *dev) |
|---|
| 2038 | +{ |
|---|
| 2039 | + struct dwc3 *dwc = dev_get_drvdata(dev); |
|---|
| 2040 | + u32 reg; |
|---|
| 2041 | + |
|---|
| 2042 | + if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST && |
|---|
| 2043 | + dwc->dis_split_quirk) { |
|---|
| 2044 | + reg = dwc3_readl(dwc->regs, DWC3_GUCTL3); |
|---|
| 2045 | + reg |= DWC3_GUCTL3_SPLITDISABLE; |
|---|
| 2046 | + dwc3_writel(dwc->regs, DWC3_GUCTL3, reg); |
|---|
| 2047 | + } |
|---|
| 2048 | +} |
|---|
| 2049 | +#else |
|---|
| 2050 | +#define dwc3_complete NULL |
|---|
| 2104 | 2051 | #endif /* CONFIG_PM_SLEEP */ |
|---|
| 2105 | 2052 | |
|---|
| 2106 | 2053 | static const struct dev_pm_ops dwc3_dev_pm_ops = { |
|---|
| 2107 | 2054 | SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume) |
|---|
| 2055 | + .complete = dwc3_complete, |
|---|
| 2108 | 2056 | SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume, |
|---|
| 2109 | 2057 | dwc3_runtime_idle) |
|---|
| 2110 | 2058 | }; |
|---|