1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2012 Freescale Semiconductor, Inc. 4 * Copyright 2025 NXP 5 */ 6 7 #include <linux/module.h> 8 #include <linux/of.h> 9 #include <linux/err.h> 10 #include <linux/io.h> 11 #include <linux/delay.h> 12 #include <linux/platform_device.h> 13 #include <linux/usb/otg.h> 14 15 #include "ci_hdrc_imx.h" 16 17 #define MX25_USB_PHY_CTRL_OFFSET 0x08 18 #define MX25_BM_EXTERNAL_VBUS_DIVIDER BIT(23) 19 20 #define MX25_EHCI_INTERFACE_SINGLE_UNI (2 << 0) 21 #define MX25_EHCI_INTERFACE_DIFF_UNI (0 << 0) 22 #define MX25_EHCI_INTERFACE_MASK (0xf) 23 24 #define MX25_OTG_SIC_SHIFT 29 25 #define MX25_OTG_SIC_MASK (0x3 << MX25_OTG_SIC_SHIFT) 26 #define MX25_OTG_PM_BIT BIT(24) 27 #define MX25_OTG_PP_BIT BIT(11) 28 #define MX25_OTG_OCPOL_BIT BIT(3) 29 30 #define MX25_H1_SIC_SHIFT 21 31 #define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT) 32 #define MX25_H1_PP_BIT BIT(18) 33 #define MX25_H1_PM_BIT BIT(16) 34 #define MX25_H1_IPPUE_UP_BIT BIT(7) 35 #define MX25_H1_IPPUE_DOWN_BIT BIT(6) 36 #define MX25_H1_TLL_BIT BIT(5) 37 #define MX25_H1_USBTE_BIT BIT(4) 38 #define MX25_H1_OCPOL_BIT BIT(2) 39 40 #define MX27_H1_PM_BIT BIT(8) 41 #define MX27_H2_PM_BIT BIT(16) 42 #define MX27_OTG_PM_BIT BIT(24) 43 44 #define MX53_USB_OTG_PHY_CTRL_0_OFFSET 0x08 45 #define MX53_USB_OTG_PHY_CTRL_1_OFFSET 0x0c 46 #define MX53_USB_CTRL_1_OFFSET 0x10 47 #define MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_MASK (0x11 << 2) 48 #define MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_ULPI BIT(2) 49 #define MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_MASK (0x11 << 6) 50 #define MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_ULPI BIT(6) 51 #define MX53_USB_UH2_CTRL_OFFSET 0x14 52 #define MX53_USB_UH3_CTRL_OFFSET 0x18 53 #define MX53_USB_CLKONOFF_CTRL_OFFSET 0x24 54 #define MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF BIT(21) 55 #define MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF BIT(22) 56 #define MX53_BM_OVER_CUR_DIS_H1 BIT(5) 57 #define MX53_BM_OVER_CUR_DIS_OTG BIT(8) 58 #define MX53_BM_OVER_CUR_DIS_UHx BIT(30) 59 #define MX53_USB_CTRL_1_UH2_ULPI_EN BIT(26) 60 #define MX53_USB_CTRL_1_UH3_ULPI_EN BIT(27) 61 #define MX53_USB_UHx_CTRL_WAKE_UP_EN BIT(7) 62 #define MX53_USB_UHx_CTRL_ULPI_INT_EN BIT(8) 63 #define MX53_USB_PHYCTRL1_PLLDIV_MASK 0x3 64 #define MX53_USB_PLL_DIV_24_MHZ 0x01 65 66 #define MX6_BM_NON_BURST_SETTING BIT(1) 67 #define MX6_BM_OVER_CUR_DIS BIT(7) 68 #define MX6_BM_OVER_CUR_POLARITY BIT(8) 69 #define MX6_BM_PWR_POLARITY BIT(9) 70 #define MX6_BM_WAKEUP_ENABLE BIT(10) 71 #define MX6_BM_UTMI_ON_CLOCK BIT(13) 72 #define MX6_BM_ID_WAKEUP BIT(16) 73 #define MX6_BM_VBUS_WAKEUP BIT(17) 74 #define MX6SX_BM_DPDM_WAKEUP_EN BIT(29) 75 #define MX6_BM_WAKEUP_INTR BIT(31) 76 77 #define MX6_USB_HSIC_CTRL_OFFSET 0x10 78 /* Send resume signal without 480Mhz PHY clock */ 79 #define MX6SX_BM_HSIC_AUTO_RESUME BIT(23) 80 /* set before portsc.suspendM = 1 */ 81 #define MX6_BM_HSIC_DEV_CONN BIT(21) 82 /* HSIC enable */ 83 #define MX6_BM_HSIC_EN BIT(12) 84 /* Force HSIC module 480M clock on, even when in Host is in suspend mode */ 85 #define MX6_BM_HSIC_CLK_ON BIT(11) 86 87 #define MX6_USB_OTG1_PHY_CTRL 0x18 88 /* For imx6dql, it is host-only controller, for later imx6, it is otg's */ 89 #define MX6_USB_OTG2_PHY_CTRL 0x1c 90 #define MX6SX_USB_VBUS_WAKEUP_SOURCE(v) (v << 8) 91 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_VBUS MX6SX_USB_VBUS_WAKEUP_SOURCE(0) 92 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_AVALID MX6SX_USB_VBUS_WAKEUP_SOURCE(1) 93 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID MX6SX_USB_VBUS_WAKEUP_SOURCE(2) 94 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_SESS_END MX6SX_USB_VBUS_WAKEUP_SOURCE(3) 95 96 #define VF610_OVER_CUR_DIS BIT(7) 97 98 #define MX7D_USBNC_USB_CTRL2 0x4 99 #define MX7D_USB_VBUS_WAKEUP_SOURCE_MASK 0x3 100 #define MX7D_USB_VBUS_WAKEUP_SOURCE(v) (v << 0) 101 #define MX7D_USB_VBUS_WAKEUP_SOURCE_VBUS MX7D_USB_VBUS_WAKEUP_SOURCE(0) 102 #define MX7D_USB_VBUS_WAKEUP_SOURCE_AVALID MX7D_USB_VBUS_WAKEUP_SOURCE(1) 103 #define MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID MX7D_USB_VBUS_WAKEUP_SOURCE(2) 104 #define MX7D_USB_VBUS_WAKEUP_SOURCE_SESS_END MX7D_USB_VBUS_WAKEUP_SOURCE(3) 105 #define MX7D_USBNC_AUTO_RESUME BIT(2) 106 /* The default DM/DP value is pull-down */ 107 #define MX7D_USBNC_USB_CTRL2_OPMODE(v) (v << 6) 108 #define MX7D_USBNC_USB_CTRL2_OPMODE_NON_DRIVING MX7D_USBNC_USB_CTRL2_OPMODE(1) 109 #define MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK (BIT(7) | BIT(6)) 110 #define MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN BIT(8) 111 #define MX7D_USBNC_USB_CTRL2_DP_OVERRIDE_VAL BIT(12) 112 #define MX7D_USBNC_USB_CTRL2_DP_OVERRIDE_EN BIT(13) 113 #define MX7D_USBNC_USB_CTRL2_DM_OVERRIDE_VAL BIT(14) 114 #define MX7D_USBNC_USB_CTRL2_DM_OVERRIDE_EN BIT(15) 115 #define MX7D_USBNC_USB_CTRL2_DP_DM_MASK (BIT(12) | BIT(13) | \ 116 BIT(14) | BIT(15)) 117 118 #define MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL BIT(0) 119 #define MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0 BIT(1) 120 #define MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 BIT(2) 121 #define MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB BIT(3) 122 #define MX7D_USB_OTG_PHY_CFG2_DRVVBUS0 BIT(16) 123 124 #define MX7D_USB_OTG_PHY_CFG2 0x34 125 126 #define MX7D_USB_OTG_PHY_STATUS 0x3c 127 #define MX7D_USB_OTG_PHY_STATUS_LINE_STATE0 BIT(0) 128 #define MX7D_USB_OTG_PHY_STATUS_LINE_STATE1 BIT(1) 129 #define MX7D_USB_OTG_PHY_STATUS_VBUS_VLD BIT(3) 130 #define MX7D_USB_OTG_PHY_STATUS_CHRGDET BIT(29) 131 132 #define MX7D_USB_OTG_PHY_CFG1 0x30 133 #define TXPREEMPAMPTUNE0_BIT 28 134 #define TXPREEMPAMPTUNE0_MASK (3 << 28) 135 #define TXRISETUNE0_BIT 24 136 #define TXRISETUNE0_MASK (3 << 24) 137 #define TXVREFTUNE0_BIT 20 138 #define TXVREFTUNE0_MASK (0xf << 20) 139 140 #define MX6_USB_OTG_WAKEUP_BITS (MX6_BM_WAKEUP_ENABLE | MX6_BM_VBUS_WAKEUP | \ 141 MX6_BM_ID_WAKEUP | MX6SX_BM_DPDM_WAKEUP_EN) 142 143 /* 144 * HSIO Block Control Register 145 */ 146 147 #define BLKCTL_USB_WAKEUP_CTRL 0x0 148 #define BLKCTL_OTG_WAKE_ENABLE BIT(31) 149 #define BLKCTL_OTG_VBUS_SESSVALID BIT(4) 150 #define BLKCTL_OTG_ID_WAKEUP_EN BIT(2) 151 #define BLKCTL_OTG_VBUS_WAKEUP_EN BIT(1) 152 #define BLKCTL_OTG_DPDM_WAKEUP_EN BIT(0) 153 154 #define BLKCTL_WAKEUP_SOURCE (BLKCTL_OTG_WAKE_ENABLE | \ 155 BLKCTL_OTG_ID_WAKEUP_EN | \ 156 BLKCTL_OTG_VBUS_WAKEUP_EN | \ 157 BLKCTL_OTG_DPDM_WAKEUP_EN) 158 159 #define S32G_WAKEUP_IE BIT(0) 160 #define S32G_CORE_IE BIT(1) 161 #define S32G_PWRFLTEN BIT(7) 162 #define S32G_WAKEUPCTRL BIT(10) 163 #define S32G_WAKEUPEN BIT(11) 164 165 /* Workaround errata ERR050474 (handle packages that aren't 4 byte aligned) */ 166 #define S32G_UCMALLBE BIT(15) 167 168 #define S32G_WAKEUP_BITS (S32G_WAKEUP_IE | S32G_CORE_IE | S32G_WAKEUPEN | \ 169 S32G_WAKEUPCTRL) 170 171 struct usbmisc_ops { 172 /* It's called once when probe a usb device */ 173 int (*init)(struct imx_usbmisc_data *data); 174 /* It's called once after adding a usb device */ 175 int (*post)(struct imx_usbmisc_data *data); 176 /* It's called when we need to enable/disable usb wakeup */ 177 int (*set_wakeup)(struct imx_usbmisc_data *data, bool enabled); 178 /* It's called before setting portsc.suspendM */ 179 int (*hsic_set_connect)(struct imx_usbmisc_data *data); 180 /* It's called during suspend/resume */ 181 int (*hsic_set_clk)(struct imx_usbmisc_data *data, bool enabled); 182 /* usb charger detection */ 183 int (*charger_detection)(struct imx_usbmisc_data *data); 184 /* It's called when system resume from usb power lost */ 185 int (*power_lost_check)(struct imx_usbmisc_data *data); 186 /* It's called when device controller changed pullup status */ 187 void (*pullup)(struct imx_usbmisc_data *data, bool on); 188 /* It's called during suspend/resume to save power */ 189 void (*vbus_comparator_on)(struct imx_usbmisc_data *data, bool on); 190 }; 191 192 struct imx_usbmisc { 193 void __iomem *base; 194 void __iomem *blkctl; 195 spinlock_t lock; 196 const struct usbmisc_ops *ops; 197 }; 198 199 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data); 200 201 static int usbmisc_imx25_init(struct imx_usbmisc_data *data) 202 { 203 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 204 unsigned long flags; 205 u32 val = 0; 206 207 if (data->index > 1) 208 return -EINVAL; 209 210 spin_lock_irqsave(&usbmisc->lock, flags); 211 switch (data->index) { 212 case 0: 213 val = readl(usbmisc->base); 214 val &= ~(MX25_OTG_SIC_MASK | MX25_OTG_PP_BIT); 215 val |= (MX25_EHCI_INTERFACE_DIFF_UNI & MX25_EHCI_INTERFACE_MASK) << MX25_OTG_SIC_SHIFT; 216 val |= (MX25_OTG_PM_BIT | MX25_OTG_OCPOL_BIT); 217 218 /* 219 * If the polarity is not configured assume active high for 220 * historical reasons. 221 */ 222 if (data->oc_pol_configured && data->oc_pol_active_low) 223 val &= ~MX25_OTG_OCPOL_BIT; 224 225 writel(val, usbmisc->base); 226 break; 227 case 1: 228 val = readl(usbmisc->base); 229 val &= ~(MX25_H1_SIC_MASK | MX25_H1_PP_BIT | MX25_H1_IPPUE_UP_BIT); 230 val |= (MX25_EHCI_INTERFACE_SINGLE_UNI & MX25_EHCI_INTERFACE_MASK) << MX25_H1_SIC_SHIFT; 231 val |= (MX25_H1_PM_BIT | MX25_H1_OCPOL_BIT | MX25_H1_TLL_BIT | 232 MX25_H1_USBTE_BIT | MX25_H1_IPPUE_DOWN_BIT); 233 234 /* 235 * If the polarity is not configured assume active high for 236 * historical reasons. 237 */ 238 if (data->oc_pol_configured && data->oc_pol_active_low) 239 val &= ~MX25_H1_OCPOL_BIT; 240 241 writel(val, usbmisc->base); 242 243 break; 244 } 245 spin_unlock_irqrestore(&usbmisc->lock, flags); 246 247 return 0; 248 } 249 250 static int usbmisc_imx25_post(struct imx_usbmisc_data *data) 251 { 252 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 253 void __iomem *reg; 254 unsigned long flags; 255 u32 val; 256 257 if (data->index > 2) 258 return -EINVAL; 259 260 if (data->index) 261 return 0; 262 263 spin_lock_irqsave(&usbmisc->lock, flags); 264 reg = usbmisc->base + MX25_USB_PHY_CTRL_OFFSET; 265 val = readl(reg); 266 267 if (data->evdo) 268 val |= MX25_BM_EXTERNAL_VBUS_DIVIDER; 269 else 270 val &= ~MX25_BM_EXTERNAL_VBUS_DIVIDER; 271 272 writel(val, reg); 273 spin_unlock_irqrestore(&usbmisc->lock, flags); 274 usleep_range(5000, 10000); /* needed to stabilize voltage */ 275 276 return 0; 277 } 278 279 static int usbmisc_imx27_init(struct imx_usbmisc_data *data) 280 { 281 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 282 unsigned long flags; 283 u32 val; 284 285 switch (data->index) { 286 case 0: 287 val = MX27_OTG_PM_BIT; 288 break; 289 case 1: 290 val = MX27_H1_PM_BIT; 291 break; 292 case 2: 293 val = MX27_H2_PM_BIT; 294 break; 295 default: 296 return -EINVAL; 297 } 298 299 spin_lock_irqsave(&usbmisc->lock, flags); 300 if (data->disable_oc) 301 val = readl(usbmisc->base) | val; 302 else 303 val = readl(usbmisc->base) & ~val; 304 writel(val, usbmisc->base); 305 spin_unlock_irqrestore(&usbmisc->lock, flags); 306 307 return 0; 308 } 309 310 static int usbmisc_imx53_init(struct imx_usbmisc_data *data) 311 { 312 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 313 void __iomem *reg = NULL; 314 unsigned long flags; 315 u32 val = 0; 316 317 if (data->index > 3) 318 return -EINVAL; 319 320 /* Select a 24 MHz reference clock for the PHY */ 321 val = readl(usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET); 322 val &= ~MX53_USB_PHYCTRL1_PLLDIV_MASK; 323 val |= MX53_USB_PLL_DIV_24_MHZ; 324 writel(val, usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET); 325 326 spin_lock_irqsave(&usbmisc->lock, flags); 327 328 switch (data->index) { 329 case 0: 330 if (data->disable_oc) { 331 reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET; 332 val = readl(reg) | MX53_BM_OVER_CUR_DIS_OTG; 333 writel(val, reg); 334 } 335 break; 336 case 1: 337 if (data->disable_oc) { 338 reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET; 339 val = readl(reg) | MX53_BM_OVER_CUR_DIS_H1; 340 writel(val, reg); 341 } 342 break; 343 case 2: 344 if (data->ulpi) { 345 /* set USBH2 into ULPI-mode. */ 346 reg = usbmisc->base + MX53_USB_CTRL_1_OFFSET; 347 val = readl(reg) | MX53_USB_CTRL_1_UH2_ULPI_EN; 348 /* select ULPI clock */ 349 val &= ~MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_MASK; 350 val |= MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_ULPI; 351 writel(val, reg); 352 /* Set interrupt wake up enable */ 353 reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET; 354 val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN 355 | MX53_USB_UHx_CTRL_ULPI_INT_EN; 356 writel(val, reg); 357 if (is_imx53_usbmisc(data)) { 358 /* Disable internal 60Mhz clock */ 359 reg = usbmisc->base + 360 MX53_USB_CLKONOFF_CTRL_OFFSET; 361 val = readl(reg) | 362 MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF; 363 writel(val, reg); 364 } 365 366 } 367 if (data->disable_oc) { 368 reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET; 369 val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx; 370 writel(val, reg); 371 } 372 break; 373 case 3: 374 if (data->ulpi) { 375 /* set USBH3 into ULPI-mode. */ 376 reg = usbmisc->base + MX53_USB_CTRL_1_OFFSET; 377 val = readl(reg) | MX53_USB_CTRL_1_UH3_ULPI_EN; 378 /* select ULPI clock */ 379 val &= ~MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_MASK; 380 val |= MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_ULPI; 381 writel(val, reg); 382 /* Set interrupt wake up enable */ 383 reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET; 384 val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN 385 | MX53_USB_UHx_CTRL_ULPI_INT_EN; 386 writel(val, reg); 387 388 if (is_imx53_usbmisc(data)) { 389 /* Disable internal 60Mhz clock */ 390 reg = usbmisc->base + 391 MX53_USB_CLKONOFF_CTRL_OFFSET; 392 val = readl(reg) | 393 MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF; 394 writel(val, reg); 395 } 396 } 397 if (data->disable_oc) { 398 reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET; 399 val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx; 400 writel(val, reg); 401 } 402 break; 403 } 404 405 spin_unlock_irqrestore(&usbmisc->lock, flags); 406 407 return 0; 408 } 409 410 static u32 usbmisc_wakeup_setting(struct imx_usbmisc_data *data) 411 { 412 u32 wakeup_setting = MX6_USB_OTG_WAKEUP_BITS; 413 414 if (data->ext_id || data->available_role != USB_DR_MODE_OTG) 415 wakeup_setting &= ~MX6_BM_ID_WAKEUP; 416 417 if (data->ext_vbus || data->available_role == USB_DR_MODE_HOST) 418 wakeup_setting &= ~MX6_BM_VBUS_WAKEUP; 419 420 return wakeup_setting; 421 } 422 423 static int usbmisc_imx6q_set_wakeup 424 (struct imx_usbmisc_data *data, bool enabled) 425 { 426 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 427 unsigned long flags; 428 u32 val; 429 int ret = 0; 430 431 if (data->index > 3) 432 return -EINVAL; 433 434 spin_lock_irqsave(&usbmisc->lock, flags); 435 val = readl(usbmisc->base + data->index * 4); 436 if (enabled) { 437 val &= ~MX6_USB_OTG_WAKEUP_BITS; 438 val |= usbmisc_wakeup_setting(data); 439 } else { 440 if (val & MX6_BM_WAKEUP_INTR) 441 pr_debug("wakeup int at ci_hdrc.%d\n", data->index); 442 val &= ~MX6_USB_OTG_WAKEUP_BITS; 443 } 444 writel(val, usbmisc->base + data->index * 4); 445 spin_unlock_irqrestore(&usbmisc->lock, flags); 446 447 return ret; 448 } 449 450 static int usbmisc_imx6q_init(struct imx_usbmisc_data *data) 451 { 452 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 453 unsigned long flags; 454 u32 reg; 455 456 if (data->index > 3) 457 return -EINVAL; 458 459 spin_lock_irqsave(&usbmisc->lock, flags); 460 461 reg = readl(usbmisc->base + data->index * 4); 462 if (data->disable_oc) { 463 reg |= MX6_BM_OVER_CUR_DIS; 464 } else { 465 reg &= ~MX6_BM_OVER_CUR_DIS; 466 467 /* 468 * If the polarity is not configured keep it as setup by the 469 * bootloader. 470 */ 471 if (data->oc_pol_configured && data->oc_pol_active_low) 472 reg |= MX6_BM_OVER_CUR_POLARITY; 473 else if (data->oc_pol_configured) 474 reg &= ~MX6_BM_OVER_CUR_POLARITY; 475 } 476 /* If the polarity is not set keep it as setup by the bootloader */ 477 if (data->pwr_pol == 1) 478 reg |= MX6_BM_PWR_POLARITY; 479 writel(reg, usbmisc->base + data->index * 4); 480 481 /* SoC non-burst setting */ 482 reg = readl(usbmisc->base + data->index * 4); 483 writel(reg | MX6_BM_NON_BURST_SETTING, 484 usbmisc->base + data->index * 4); 485 486 /* For HSIC controller */ 487 if (data->hsic) { 488 reg = readl(usbmisc->base + data->index * 4); 489 writel(reg | MX6_BM_UTMI_ON_CLOCK, 490 usbmisc->base + data->index * 4); 491 reg = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET 492 + (data->index - 2) * 4); 493 reg |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON; 494 writel(reg, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET 495 + (data->index - 2) * 4); 496 } 497 498 spin_unlock_irqrestore(&usbmisc->lock, flags); 499 500 usbmisc_imx6q_set_wakeup(data, false); 501 502 return 0; 503 } 504 505 static int usbmisc_imx6_hsic_get_reg_offset(struct imx_usbmisc_data *data) 506 { 507 int offset, ret = 0; 508 509 if (data->index == 2 || data->index == 3) { 510 offset = (data->index - 2) * 4; 511 } else if (data->index == 0) { 512 /* 513 * For SoCs like i.MX7D and later, each USB controller has 514 * its own non-core register region. For SoCs before i.MX7D, 515 * the first two USB controllers are non-HSIC controllers. 516 */ 517 offset = 0; 518 } else { 519 dev_err(data->dev, "index is error for usbmisc\n"); 520 ret = -EINVAL; 521 } 522 523 return ret ? ret : offset; 524 } 525 526 static int usbmisc_imx6_hsic_set_connect(struct imx_usbmisc_data *data) 527 { 528 unsigned long flags; 529 u32 val; 530 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 531 int offset; 532 533 spin_lock_irqsave(&usbmisc->lock, flags); 534 offset = usbmisc_imx6_hsic_get_reg_offset(data); 535 if (offset < 0) { 536 spin_unlock_irqrestore(&usbmisc->lock, flags); 537 return offset; 538 } 539 540 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); 541 if (!(val & MX6_BM_HSIC_DEV_CONN)) 542 writel(val | MX6_BM_HSIC_DEV_CONN, 543 usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); 544 545 spin_unlock_irqrestore(&usbmisc->lock, flags); 546 547 return 0; 548 } 549 550 static int usbmisc_imx6_hsic_set_clk(struct imx_usbmisc_data *data, bool on) 551 { 552 unsigned long flags; 553 u32 val; 554 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 555 int offset; 556 557 spin_lock_irqsave(&usbmisc->lock, flags); 558 offset = usbmisc_imx6_hsic_get_reg_offset(data); 559 if (offset < 0) { 560 spin_unlock_irqrestore(&usbmisc->lock, flags); 561 return offset; 562 } 563 564 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); 565 val |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON; 566 if (on) 567 val |= MX6_BM_HSIC_CLK_ON; 568 else 569 val &= ~MX6_BM_HSIC_CLK_ON; 570 571 writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); 572 spin_unlock_irqrestore(&usbmisc->lock, flags); 573 574 return 0; 575 } 576 577 578 static int usbmisc_imx6sx_init(struct imx_usbmisc_data *data) 579 { 580 void __iomem *reg = NULL; 581 unsigned long flags; 582 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 583 u32 val; 584 585 usbmisc_imx6q_init(data); 586 587 if (data->index == 0 || data->index == 1) { 588 reg = usbmisc->base + MX6_USB_OTG1_PHY_CTRL + data->index * 4; 589 spin_lock_irqsave(&usbmisc->lock, flags); 590 /* Set vbus wakeup source as bvalid */ 591 val = readl(reg); 592 writel(val | MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID, reg); 593 /* 594 * Disable dp/dm wakeup in device mode when vbus is 595 * not there. 596 */ 597 val = readl(usbmisc->base + data->index * 4); 598 writel(val & ~MX6SX_BM_DPDM_WAKEUP_EN, 599 usbmisc->base + data->index * 4); 600 spin_unlock_irqrestore(&usbmisc->lock, flags); 601 } 602 603 /* For HSIC controller */ 604 if (data->hsic) { 605 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); 606 val |= MX6SX_BM_HSIC_AUTO_RESUME; 607 writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); 608 } 609 610 return 0; 611 } 612 613 static int usbmisc_vf610_init(struct imx_usbmisc_data *data) 614 { 615 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 616 u32 reg; 617 618 /* 619 * Vybrid only has one misc register set, but in two different 620 * areas. These is reflected in two instances of this driver. 621 */ 622 if (data->index >= 1) 623 return -EINVAL; 624 625 if (data->disable_oc) { 626 reg = readl(usbmisc->base); 627 writel(reg | VF610_OVER_CUR_DIS, usbmisc->base); 628 } 629 630 return 0; 631 } 632 633 static int usbmisc_s32g_set_wakeup(struct imx_usbmisc_data *data, bool enabled) 634 { 635 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 636 unsigned long flags; 637 u32 reg; 638 639 spin_lock_irqsave(&usbmisc->lock, flags); 640 641 reg = readl(usbmisc->base); 642 if (enabled) 643 reg |= S32G_WAKEUP_BITS; 644 else 645 reg &= ~S32G_WAKEUP_BITS; 646 647 writel(reg, usbmisc->base); 648 spin_unlock_irqrestore(&usbmisc->lock, flags); 649 650 return 0; 651 } 652 653 static int usbmisc_s32g_init(struct imx_usbmisc_data *data, u32 extra_flags) 654 { 655 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 656 unsigned long flags; 657 u32 reg; 658 659 spin_lock_irqsave(&usbmisc->lock, flags); 660 661 reg = readl(usbmisc->base); 662 663 reg |= S32G_PWRFLTEN; 664 reg |= extra_flags; 665 666 writel(reg, usbmisc->base); 667 668 spin_unlock_irqrestore(&usbmisc->lock, flags); 669 usbmisc_s32g_set_wakeup(data, false); 670 671 return 0; 672 } 673 674 static int usbmisc_s32g2_init(struct imx_usbmisc_data *data) 675 { 676 return usbmisc_s32g_init(data, S32G_UCMALLBE); 677 } 678 679 static int usbmisc_s32g3_init(struct imx_usbmisc_data *data) 680 { 681 return usbmisc_s32g_init(data, 0); 682 } 683 684 static int usbmisc_imx7d_set_wakeup 685 (struct imx_usbmisc_data *data, bool enabled) 686 { 687 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 688 unsigned long flags; 689 u32 val; 690 691 spin_lock_irqsave(&usbmisc->lock, flags); 692 val = readl(usbmisc->base); 693 if (enabled) { 694 val &= ~MX6_USB_OTG_WAKEUP_BITS; 695 val |= usbmisc_wakeup_setting(data); 696 writel(val, usbmisc->base); 697 } else { 698 if (val & MX6_BM_WAKEUP_INTR) 699 dev_dbg(data->dev, "wakeup int\n"); 700 writel(val & ~MX6_USB_OTG_WAKEUP_BITS, usbmisc->base); 701 } 702 spin_unlock_irqrestore(&usbmisc->lock, flags); 703 704 return 0; 705 } 706 707 static int usbmisc_imx7d_init(struct imx_usbmisc_data *data) 708 { 709 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 710 unsigned long flags; 711 u32 reg; 712 713 if (data->index >= 1) 714 return -EINVAL; 715 716 spin_lock_irqsave(&usbmisc->lock, flags); 717 reg = readl(usbmisc->base); 718 if (data->disable_oc) { 719 reg |= MX6_BM_OVER_CUR_DIS; 720 } else { 721 reg &= ~MX6_BM_OVER_CUR_DIS; 722 723 /* 724 * If the polarity is not configured keep it as setup by the 725 * bootloader. 726 */ 727 if (data->oc_pol_configured && data->oc_pol_active_low) 728 reg |= MX6_BM_OVER_CUR_POLARITY; 729 else if (data->oc_pol_configured) 730 reg &= ~MX6_BM_OVER_CUR_POLARITY; 731 } 732 /* If the polarity is not set keep it as setup by the bootloader */ 733 if (data->pwr_pol == 1) 734 reg |= MX6_BM_PWR_POLARITY; 735 writel(reg, usbmisc->base); 736 737 /* SoC non-burst setting */ 738 reg = readl(usbmisc->base); 739 writel(reg | MX6_BM_NON_BURST_SETTING, usbmisc->base); 740 741 if (!data->hsic) { 742 reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 743 reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK; 744 writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID 745 | MX7D_USBNC_AUTO_RESUME, 746 usbmisc->base + MX7D_USBNC_USB_CTRL2); 747 /* PHY tuning for signal quality */ 748 reg = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG1); 749 if (data->emp_curr_control >= 0 && 750 data->emp_curr_control <= 751 (TXPREEMPAMPTUNE0_MASK >> TXPREEMPAMPTUNE0_BIT)) { 752 reg &= ~TXPREEMPAMPTUNE0_MASK; 753 reg |= (data->emp_curr_control << TXPREEMPAMPTUNE0_BIT); 754 } 755 756 if (data->dc_vol_level_adjust >= 0 && 757 data->dc_vol_level_adjust <= 758 (TXVREFTUNE0_MASK >> TXVREFTUNE0_BIT)) { 759 reg &= ~TXVREFTUNE0_MASK; 760 reg |= (data->dc_vol_level_adjust << TXVREFTUNE0_BIT); 761 } 762 763 if (data->rise_fall_time_adjust >= 0 && 764 data->rise_fall_time_adjust <= 765 (TXRISETUNE0_MASK >> TXRISETUNE0_BIT)) { 766 reg &= ~TXRISETUNE0_MASK; 767 reg |= (data->rise_fall_time_adjust << TXRISETUNE0_BIT); 768 } 769 770 writel(reg, usbmisc->base + MX7D_USB_OTG_PHY_CFG1); 771 } 772 773 spin_unlock_irqrestore(&usbmisc->lock, flags); 774 775 usbmisc_imx7d_set_wakeup(data, false); 776 777 return 0; 778 } 779 780 static int imx7d_charger_secondary_detection(struct imx_usbmisc_data *data) 781 { 782 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 783 struct usb_phy *usb_phy = data->usb_phy; 784 int val; 785 unsigned long flags; 786 787 /* Clear VDATSRCENB0 to disable VDP_SRC and IDM_SNK required by BC 1.2 spec */ 788 spin_lock_irqsave(&usbmisc->lock, flags); 789 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 790 val &= ~MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0; 791 writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 792 spin_unlock_irqrestore(&usbmisc->lock, flags); 793 794 /* TVDMSRC_DIS */ 795 msleep(20); 796 797 /* VDM_SRC is connected to D- and IDP_SINK is connected to D+ */ 798 spin_lock_irqsave(&usbmisc->lock, flags); 799 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 800 writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 | 801 MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0 | 802 MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL, 803 usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 804 spin_unlock_irqrestore(&usbmisc->lock, flags); 805 806 /* TVDMSRC_ON */ 807 msleep(40); 808 809 /* 810 * Per BC 1.2, check voltage of D+: 811 * DCP: if greater than VDAT_REF; 812 * CDP: if less than VDAT_REF. 813 */ 814 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS); 815 if (val & MX7D_USB_OTG_PHY_STATUS_CHRGDET) { 816 dev_dbg(data->dev, "It is a dedicate charging port\n"); 817 usb_phy->chg_type = DCP_TYPE; 818 } else { 819 dev_dbg(data->dev, "It is a charging downstream port\n"); 820 usb_phy->chg_type = CDP_TYPE; 821 } 822 823 return 0; 824 } 825 826 static void imx7_disable_charger_detector(struct imx_usbmisc_data *data) 827 { 828 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 829 unsigned long flags; 830 u32 val; 831 832 spin_lock_irqsave(&usbmisc->lock, flags); 833 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 834 val &= ~(MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB | 835 MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 | 836 MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0 | 837 MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL); 838 writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 839 840 /* Set OPMODE to be 2'b00 and disable its override */ 841 val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 842 val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK; 843 writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2); 844 845 val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 846 writel(val & ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN, 847 usbmisc->base + MX7D_USBNC_USB_CTRL2); 848 spin_unlock_irqrestore(&usbmisc->lock, flags); 849 } 850 851 static int imx7d_charger_data_contact_detect(struct imx_usbmisc_data *data) 852 { 853 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 854 unsigned long flags; 855 u32 val; 856 int i, data_pin_contact_count = 0; 857 858 /* Enable Data Contact Detect (DCD) per the USB BC 1.2 */ 859 spin_lock_irqsave(&usbmisc->lock, flags); 860 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 861 writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB, 862 usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 863 spin_unlock_irqrestore(&usbmisc->lock, flags); 864 865 for (i = 0; i < 100; i = i + 1) { 866 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS); 867 if (!(val & MX7D_USB_OTG_PHY_STATUS_LINE_STATE0)) { 868 if (data_pin_contact_count++ > 5) 869 /* Data pin makes contact */ 870 break; 871 usleep_range(5000, 10000); 872 } else { 873 data_pin_contact_count = 0; 874 usleep_range(5000, 6000); 875 } 876 } 877 878 /* Disable DCD after finished data contact check */ 879 spin_lock_irqsave(&usbmisc->lock, flags); 880 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 881 writel(val & ~MX7D_USB_OTG_PHY_CFG2_CHRG_DCDENB, 882 usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 883 spin_unlock_irqrestore(&usbmisc->lock, flags); 884 885 if (i == 100) { 886 dev_err(data->dev, 887 "VBUS is coming from a dedicated power supply.\n"); 888 return -ENXIO; 889 } 890 891 return 0; 892 } 893 894 static int imx7d_charger_primary_detection(struct imx_usbmisc_data *data) 895 { 896 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 897 struct usb_phy *usb_phy = data->usb_phy; 898 unsigned long flags; 899 u32 val; 900 901 /* VDP_SRC is connected to D+ and IDM_SINK is connected to D- */ 902 spin_lock_irqsave(&usbmisc->lock, flags); 903 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 904 val &= ~MX7D_USB_OTG_PHY_CFG2_CHRG_CHRGSEL; 905 writel(val | MX7D_USB_OTG_PHY_CFG2_CHRG_VDATSRCENB0 | 906 MX7D_USB_OTG_PHY_CFG2_CHRG_VDATDETENB0, 907 usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 908 spin_unlock_irqrestore(&usbmisc->lock, flags); 909 910 /* TVDPSRC_ON */ 911 msleep(40); 912 913 /* Check if D- is less than VDAT_REF to determine an SDP per BC 1.2 */ 914 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS); 915 if (!(val & MX7D_USB_OTG_PHY_STATUS_CHRGDET)) { 916 dev_dbg(data->dev, "It is a standard downstream port\n"); 917 usb_phy->chg_type = SDP_TYPE; 918 } 919 920 return 0; 921 } 922 923 /* 924 * Whole charger detection process: 925 * 1. OPMODE override to be non-driving 926 * 2. Data contact check 927 * 3. Primary detection 928 * 4. Secondary detection 929 * 5. Disable charger detection 930 */ 931 static int imx7d_charger_detection(struct imx_usbmisc_data *data) 932 { 933 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 934 struct usb_phy *usb_phy = data->usb_phy; 935 unsigned long flags; 936 u32 val; 937 int ret; 938 939 /* Check if vbus is valid */ 940 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_STATUS); 941 if (!(val & MX7D_USB_OTG_PHY_STATUS_VBUS_VLD)) { 942 dev_err(data->dev, "vbus is error\n"); 943 return -EINVAL; 944 } 945 946 /* 947 * Keep OPMODE to be non-driving mode during the whole 948 * charger detection process. 949 */ 950 spin_lock_irqsave(&usbmisc->lock, flags); 951 val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 952 val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK; 953 val |= MX7D_USBNC_USB_CTRL2_OPMODE_NON_DRIVING; 954 writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2); 955 956 val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 957 writel(val | MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN, 958 usbmisc->base + MX7D_USBNC_USB_CTRL2); 959 spin_unlock_irqrestore(&usbmisc->lock, flags); 960 961 ret = imx7d_charger_data_contact_detect(data); 962 if (ret) 963 return ret; 964 965 ret = imx7d_charger_primary_detection(data); 966 if (!ret && usb_phy->chg_type != SDP_TYPE) 967 ret = imx7d_charger_secondary_detection(data); 968 969 imx7_disable_charger_detector(data); 970 971 return ret; 972 } 973 974 static void usbmisc_imx7d_vbus_comparator_on(struct imx_usbmisc_data *data, 975 bool on) 976 { 977 unsigned long flags; 978 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 979 u32 val; 980 981 if (data->hsic) 982 return; 983 984 spin_lock_irqsave(&usbmisc->lock, flags); 985 /* 986 * Disable VBUS valid comparator when in suspend mode, 987 * when OTG is disabled and DRVVBUS0 is asserted case 988 * the Bandgap circuitry and VBUS Valid comparator are 989 * still powered, even in Suspend or Sleep mode. 990 */ 991 val = readl(usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 992 if (on) 993 val |= MX7D_USB_OTG_PHY_CFG2_DRVVBUS0; 994 else 995 val &= ~MX7D_USB_OTG_PHY_CFG2_DRVVBUS0; 996 997 writel(val, usbmisc->base + MX7D_USB_OTG_PHY_CFG2); 998 spin_unlock_irqrestore(&usbmisc->lock, flags); 999 } 1000 1001 static int usbmisc_imx7ulp_init(struct imx_usbmisc_data *data) 1002 { 1003 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 1004 unsigned long flags; 1005 u32 reg; 1006 1007 if (data->index >= 1) 1008 return -EINVAL; 1009 1010 spin_lock_irqsave(&usbmisc->lock, flags); 1011 reg = readl(usbmisc->base); 1012 if (data->disable_oc) { 1013 reg |= MX6_BM_OVER_CUR_DIS; 1014 } else { 1015 reg &= ~MX6_BM_OVER_CUR_DIS; 1016 1017 /* 1018 * If the polarity is not configured keep it as setup by the 1019 * bootloader. 1020 */ 1021 if (data->oc_pol_configured && data->oc_pol_active_low) 1022 reg |= MX6_BM_OVER_CUR_POLARITY; 1023 else if (data->oc_pol_configured) 1024 reg &= ~MX6_BM_OVER_CUR_POLARITY; 1025 } 1026 /* If the polarity is not set keep it as setup by the bootloader */ 1027 if (data->pwr_pol == 1) 1028 reg |= MX6_BM_PWR_POLARITY; 1029 1030 writel(reg, usbmisc->base); 1031 1032 /* SoC non-burst setting */ 1033 reg = readl(usbmisc->base); 1034 writel(reg | MX6_BM_NON_BURST_SETTING, usbmisc->base); 1035 1036 if (data->hsic) { 1037 reg = readl(usbmisc->base); 1038 writel(reg | MX6_BM_UTMI_ON_CLOCK, usbmisc->base); 1039 1040 reg = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); 1041 reg |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON; 1042 writel(reg, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); 1043 1044 /* 1045 * For non-HSIC controller, the autoresume is enabled 1046 * at MXS PHY driver (usbphy_ctrl bit18). 1047 */ 1048 reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 1049 writel(reg | MX7D_USBNC_AUTO_RESUME, 1050 usbmisc->base + MX7D_USBNC_USB_CTRL2); 1051 } else { 1052 reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 1053 reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK; 1054 writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID, 1055 usbmisc->base + MX7D_USBNC_USB_CTRL2); 1056 } 1057 1058 spin_unlock_irqrestore(&usbmisc->lock, flags); 1059 1060 usbmisc_imx7d_set_wakeup(data, false); 1061 1062 return 0; 1063 } 1064 1065 static void usbmisc_imx7d_pullup(struct imx_usbmisc_data *data, bool on) 1066 { 1067 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 1068 unsigned long flags; 1069 u32 val; 1070 1071 if (on) 1072 return; 1073 1074 spin_lock_irqsave(&usbmisc->lock, flags); 1075 val = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 1076 val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK; 1077 val |= MX7D_USBNC_USB_CTRL2_OPMODE(1); 1078 val |= MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN; 1079 writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2); 1080 spin_unlock_irqrestore(&usbmisc->lock, flags); 1081 1082 /* Last for at least 1 micro-frame to let host see disconnect signal */ 1083 usleep_range(125, 150); 1084 1085 spin_lock_irqsave(&usbmisc->lock, flags); 1086 val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_MASK; 1087 val |= MX7D_USBNC_USB_CTRL2_OPMODE(0); 1088 val &= ~MX7D_USBNC_USB_CTRL2_OPMODE_OVERRIDE_EN; 1089 writel(val, usbmisc->base + MX7D_USBNC_USB_CTRL2); 1090 spin_unlock_irqrestore(&usbmisc->lock, flags); 1091 } 1092 1093 static int usbmisc_imx7d_power_lost_check(struct imx_usbmisc_data *data) 1094 { 1095 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 1096 unsigned long flags; 1097 u32 val; 1098 1099 spin_lock_irqsave(&usbmisc->lock, flags); 1100 val = readl(usbmisc->base); 1101 spin_unlock_irqrestore(&usbmisc->lock, flags); 1102 /* 1103 * Here use a power on reset value to judge 1104 * if the controller experienced a power lost 1105 */ 1106 if (val == 0x30001000) 1107 return 1; 1108 else 1109 return 0; 1110 } 1111 1112 static int usbmisc_imx6sx_power_lost_check(struct imx_usbmisc_data *data) 1113 { 1114 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 1115 unsigned long flags; 1116 u32 val; 1117 1118 spin_lock_irqsave(&usbmisc->lock, flags); 1119 val = readl(usbmisc->base + data->index * 4); 1120 spin_unlock_irqrestore(&usbmisc->lock, flags); 1121 /* 1122 * Here use a power on reset value to judge 1123 * if the controller experienced a power lost 1124 */ 1125 if (val == 0x30001000) 1126 return 1; 1127 else 1128 return 0; 1129 } 1130 1131 static int usbmisc_s32g_power_lost_check(struct imx_usbmisc_data *data) 1132 { 1133 return 1; 1134 } 1135 1136 static u32 usbmisc_blkctl_wakeup_setting(struct imx_usbmisc_data *data) 1137 { 1138 u32 wakeup_setting = BLKCTL_WAKEUP_SOURCE; 1139 1140 if (data->ext_id || data->available_role != USB_DR_MODE_OTG) 1141 wakeup_setting &= ~BLKCTL_OTG_ID_WAKEUP_EN; 1142 1143 if (data->ext_vbus || data->available_role == USB_DR_MODE_HOST) 1144 wakeup_setting &= ~BLKCTL_OTG_VBUS_WAKEUP_EN; 1145 1146 /* Select session valid as VBUS wakeup source */ 1147 wakeup_setting |= BLKCTL_OTG_VBUS_SESSVALID; 1148 1149 return wakeup_setting; 1150 } 1151 1152 static int usbmisc_imx95_set_wakeup(struct imx_usbmisc_data *data, bool enabled) 1153 { 1154 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 1155 unsigned long flags; 1156 u32 val; 1157 1158 if (!usbmisc->blkctl) 1159 return 0; 1160 1161 spin_lock_irqsave(&usbmisc->lock, flags); 1162 val = readl(usbmisc->blkctl + BLKCTL_USB_WAKEUP_CTRL); 1163 val &= ~BLKCTL_WAKEUP_SOURCE; 1164 1165 if (enabled) 1166 val |= usbmisc_blkctl_wakeup_setting(data); 1167 1168 writel(val, usbmisc->blkctl + BLKCTL_USB_WAKEUP_CTRL); 1169 spin_unlock_irqrestore(&usbmisc->lock, flags); 1170 1171 return 0; 1172 } 1173 1174 static const struct usbmisc_ops imx25_usbmisc_ops = { 1175 .init = usbmisc_imx25_init, 1176 .post = usbmisc_imx25_post, 1177 }; 1178 1179 static const struct usbmisc_ops imx27_usbmisc_ops = { 1180 .init = usbmisc_imx27_init, 1181 }; 1182 1183 static const struct usbmisc_ops imx51_usbmisc_ops = { 1184 .init = usbmisc_imx53_init, 1185 }; 1186 1187 static const struct usbmisc_ops imx53_usbmisc_ops = { 1188 .init = usbmisc_imx53_init, 1189 }; 1190 1191 static const struct usbmisc_ops imx6q_usbmisc_ops = { 1192 .set_wakeup = usbmisc_imx6q_set_wakeup, 1193 .init = usbmisc_imx6q_init, 1194 .hsic_set_connect = usbmisc_imx6_hsic_set_connect, 1195 .hsic_set_clk = usbmisc_imx6_hsic_set_clk, 1196 }; 1197 1198 static const struct usbmisc_ops vf610_usbmisc_ops = { 1199 .init = usbmisc_vf610_init, 1200 }; 1201 1202 static const struct usbmisc_ops imx6sx_usbmisc_ops = { 1203 .set_wakeup = usbmisc_imx6q_set_wakeup, 1204 .init = usbmisc_imx6sx_init, 1205 .hsic_set_connect = usbmisc_imx6_hsic_set_connect, 1206 .hsic_set_clk = usbmisc_imx6_hsic_set_clk, 1207 .power_lost_check = usbmisc_imx6sx_power_lost_check, 1208 }; 1209 1210 static const struct usbmisc_ops imx7d_usbmisc_ops = { 1211 .init = usbmisc_imx7d_init, 1212 .set_wakeup = usbmisc_imx7d_set_wakeup, 1213 .charger_detection = imx7d_charger_detection, 1214 .power_lost_check = usbmisc_imx7d_power_lost_check, 1215 .pullup = usbmisc_imx7d_pullup, 1216 .vbus_comparator_on = usbmisc_imx7d_vbus_comparator_on, 1217 }; 1218 1219 static const struct usbmisc_ops imx7ulp_usbmisc_ops = { 1220 .init = usbmisc_imx7ulp_init, 1221 .set_wakeup = usbmisc_imx7d_set_wakeup, 1222 .hsic_set_connect = usbmisc_imx6_hsic_set_connect, 1223 .hsic_set_clk = usbmisc_imx6_hsic_set_clk, 1224 .power_lost_check = usbmisc_imx7d_power_lost_check, 1225 }; 1226 1227 static const struct usbmisc_ops imx95_usbmisc_ops = { 1228 .init = usbmisc_imx7d_init, 1229 .set_wakeup = usbmisc_imx95_set_wakeup, 1230 .charger_detection = imx7d_charger_detection, 1231 .power_lost_check = usbmisc_imx7d_power_lost_check, 1232 .pullup = usbmisc_imx7d_pullup, 1233 .vbus_comparator_on = usbmisc_imx7d_vbus_comparator_on, 1234 }; 1235 1236 static const struct usbmisc_ops s32g2_usbmisc_ops = { 1237 .init = usbmisc_s32g2_init, 1238 .set_wakeup = usbmisc_s32g_set_wakeup, 1239 .power_lost_check = usbmisc_s32g_power_lost_check, 1240 }; 1241 1242 static const struct usbmisc_ops s32g3_usbmisc_ops = { 1243 .init = usbmisc_s32g3_init, 1244 .set_wakeup = usbmisc_s32g_set_wakeup, 1245 .power_lost_check = usbmisc_s32g_power_lost_check, 1246 }; 1247 1248 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data) 1249 { 1250 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 1251 1252 return usbmisc->ops == &imx53_usbmisc_ops; 1253 } 1254 1255 int imx_usbmisc_init(struct imx_usbmisc_data *data) 1256 { 1257 struct imx_usbmisc *usbmisc; 1258 1259 if (!data) 1260 return 0; 1261 1262 usbmisc = dev_get_drvdata(data->dev); 1263 if (!usbmisc->ops->init) 1264 return 0; 1265 return usbmisc->ops->init(data); 1266 } 1267 EXPORT_SYMBOL_GPL(imx_usbmisc_init); 1268 1269 int imx_usbmisc_init_post(struct imx_usbmisc_data *data) 1270 { 1271 struct imx_usbmisc *usbmisc; 1272 int ret = 0; 1273 1274 if (!data) 1275 return 0; 1276 1277 usbmisc = dev_get_drvdata(data->dev); 1278 if (usbmisc->ops->post) 1279 ret = usbmisc->ops->post(data); 1280 if (ret) { 1281 dev_err(data->dev, "post init failed, ret=%d\n", ret); 1282 return ret; 1283 } 1284 1285 if (usbmisc->ops->set_wakeup) 1286 ret = usbmisc->ops->set_wakeup(data, false); 1287 if (ret) { 1288 dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret); 1289 return ret; 1290 } 1291 1292 return 0; 1293 } 1294 EXPORT_SYMBOL_GPL(imx_usbmisc_init_post); 1295 1296 int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *data) 1297 { 1298 struct imx_usbmisc *usbmisc; 1299 1300 if (!data) 1301 return 0; 1302 1303 usbmisc = dev_get_drvdata(data->dev); 1304 if (!usbmisc->ops->hsic_set_connect || !data->hsic) 1305 return 0; 1306 return usbmisc->ops->hsic_set_connect(data); 1307 } 1308 EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_connect); 1309 1310 int imx_usbmisc_charger_detection(struct imx_usbmisc_data *data, bool connect) 1311 { 1312 struct imx_usbmisc *usbmisc; 1313 struct usb_phy *usb_phy; 1314 int ret = 0; 1315 1316 if (!data) 1317 return -EINVAL; 1318 1319 usbmisc = dev_get_drvdata(data->dev); 1320 usb_phy = data->usb_phy; 1321 if (!usbmisc->ops->charger_detection) 1322 return -ENOTSUPP; 1323 1324 if (connect) { 1325 ret = usbmisc->ops->charger_detection(data); 1326 if (ret) { 1327 dev_err(data->dev, 1328 "Error occurs during detection: %d\n", 1329 ret); 1330 usb_phy->chg_state = USB_CHARGER_ABSENT; 1331 } else { 1332 usb_phy->chg_state = USB_CHARGER_PRESENT; 1333 } 1334 } else { 1335 usb_phy->chg_state = USB_CHARGER_ABSENT; 1336 usb_phy->chg_type = UNKNOWN_TYPE; 1337 } 1338 return ret; 1339 } 1340 EXPORT_SYMBOL_GPL(imx_usbmisc_charger_detection); 1341 1342 int imx_usbmisc_pullup(struct imx_usbmisc_data *data, bool on) 1343 { 1344 struct imx_usbmisc *usbmisc; 1345 1346 if (!data) 1347 return 0; 1348 1349 usbmisc = dev_get_drvdata(data->dev); 1350 if (usbmisc->ops->pullup) 1351 usbmisc->ops->pullup(data, on); 1352 1353 return 0; 1354 } 1355 EXPORT_SYMBOL_GPL(imx_usbmisc_pullup); 1356 1357 int imx_usbmisc_suspend(struct imx_usbmisc_data *data, bool wakeup) 1358 { 1359 struct imx_usbmisc *usbmisc; 1360 int ret = 0; 1361 1362 if (!data) 1363 return 0; 1364 1365 usbmisc = dev_get_drvdata(data->dev); 1366 1367 if (usbmisc->ops->vbus_comparator_on) 1368 usbmisc->ops->vbus_comparator_on(data, false); 1369 1370 if (wakeup && usbmisc->ops->set_wakeup) 1371 ret = usbmisc->ops->set_wakeup(data, true); 1372 if (ret) { 1373 dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret); 1374 return ret; 1375 } 1376 1377 if (usbmisc->ops->hsic_set_clk && data->hsic) 1378 ret = usbmisc->ops->hsic_set_clk(data, false); 1379 if (ret) { 1380 dev_err(data->dev, "hsic_set_clk failed, ret=%d\n", ret); 1381 return ret; 1382 } 1383 1384 return ret; 1385 } 1386 EXPORT_SYMBOL_GPL(imx_usbmisc_suspend); 1387 1388 int imx_usbmisc_resume(struct imx_usbmisc_data *data, bool wakeup) 1389 { 1390 struct imx_usbmisc *usbmisc; 1391 int ret = 0; 1392 1393 if (!data) 1394 return 0; 1395 1396 usbmisc = dev_get_drvdata(data->dev); 1397 1398 if (usbmisc->ops->power_lost_check) 1399 ret = usbmisc->ops->power_lost_check(data); 1400 if (ret > 0) { 1401 /* re-init if resume from power lost */ 1402 ret = imx_usbmisc_init(data); 1403 if (ret) { 1404 dev_err(data->dev, "re-init failed, ret=%d\n", ret); 1405 return ret; 1406 } 1407 } 1408 1409 if (wakeup && usbmisc->ops->set_wakeup) 1410 ret = usbmisc->ops->set_wakeup(data, false); 1411 if (ret) { 1412 dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret); 1413 return ret; 1414 } 1415 1416 if (usbmisc->ops->hsic_set_clk && data->hsic) 1417 ret = usbmisc->ops->hsic_set_clk(data, true); 1418 if (ret) { 1419 dev_err(data->dev, "hsic_set_clk failed, ret=%d\n", ret); 1420 goto hsic_set_clk_fail; 1421 } 1422 1423 if (usbmisc->ops->vbus_comparator_on) 1424 usbmisc->ops->vbus_comparator_on(data, true); 1425 1426 return 0; 1427 1428 hsic_set_clk_fail: 1429 if (wakeup && usbmisc->ops->set_wakeup) 1430 usbmisc->ops->set_wakeup(data, true); 1431 return ret; 1432 } 1433 EXPORT_SYMBOL_GPL(imx_usbmisc_resume); 1434 1435 static const struct of_device_id usbmisc_imx_dt_ids[] = { 1436 { 1437 .compatible = "fsl,imx25-usbmisc", 1438 .data = &imx25_usbmisc_ops, 1439 }, 1440 { 1441 .compatible = "fsl,imx35-usbmisc", 1442 .data = &imx25_usbmisc_ops, 1443 }, 1444 { 1445 .compatible = "fsl,imx27-usbmisc", 1446 .data = &imx27_usbmisc_ops, 1447 }, 1448 { 1449 .compatible = "fsl,imx51-usbmisc", 1450 .data = &imx51_usbmisc_ops, 1451 }, 1452 { 1453 .compatible = "fsl,imx53-usbmisc", 1454 .data = &imx53_usbmisc_ops, 1455 }, 1456 { 1457 .compatible = "fsl,imx6q-usbmisc", 1458 .data = &imx6q_usbmisc_ops, 1459 }, 1460 { 1461 .compatible = "fsl,vf610-usbmisc", 1462 .data = &vf610_usbmisc_ops, 1463 }, 1464 { 1465 .compatible = "fsl,imx6sx-usbmisc", 1466 .data = &imx6sx_usbmisc_ops, 1467 }, 1468 { 1469 .compatible = "fsl,imx6ul-usbmisc", 1470 .data = &imx6sx_usbmisc_ops, 1471 }, 1472 { 1473 .compatible = "fsl,imx7d-usbmisc", 1474 .data = &imx7d_usbmisc_ops, 1475 }, 1476 { 1477 .compatible = "fsl,imx7ulp-usbmisc", 1478 .data = &imx7ulp_usbmisc_ops, 1479 }, 1480 { 1481 .compatible = "fsl,imx8ulp-usbmisc", 1482 .data = &imx7ulp_usbmisc_ops, 1483 }, 1484 { 1485 .compatible = "fsl,imx95-usbmisc", 1486 .data = &imx95_usbmisc_ops, 1487 }, 1488 { 1489 .compatible = "nxp,s32g2-usbmisc", 1490 .data = &s32g2_usbmisc_ops, 1491 }, 1492 { 1493 .compatible = "nxp,s32g3-usbmisc", 1494 .data = &s32g3_usbmisc_ops, 1495 }, 1496 { /* sentinel */ } 1497 }; 1498 MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids); 1499 1500 static int usbmisc_imx_probe(struct platform_device *pdev) 1501 { 1502 struct imx_usbmisc *data; 1503 struct resource *res; 1504 1505 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 1506 if (!data) 1507 return -ENOMEM; 1508 1509 spin_lock_init(&data->lock); 1510 1511 data->base = devm_platform_ioremap_resource(pdev, 0); 1512 if (IS_ERR(data->base)) 1513 return PTR_ERR(data->base); 1514 1515 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 1516 if (res) { 1517 data->blkctl = devm_ioremap_resource(&pdev->dev, res); 1518 if (IS_ERR(data->blkctl)) 1519 return PTR_ERR(data->blkctl); 1520 } else if (device_is_compatible(&pdev->dev, "fsl,imx95-usbmisc")) { 1521 dev_warn(&pdev->dev, "wakeup setting is missing\n"); 1522 } 1523 1524 data->ops = of_device_get_match_data(&pdev->dev); 1525 platform_set_drvdata(pdev, data); 1526 1527 return 0; 1528 } 1529 1530 static struct platform_driver usbmisc_imx_driver = { 1531 .probe = usbmisc_imx_probe, 1532 .driver = { 1533 .name = "usbmisc_imx", 1534 .of_match_table = usbmisc_imx_dt_ids, 1535 }, 1536 }; 1537 1538 module_platform_driver(usbmisc_imx_driver); 1539 1540 MODULE_ALIAS("platform:usbmisc-imx"); 1541 MODULE_LICENSE("GPL"); 1542 MODULE_DESCRIPTION("driver for imx usb non-core registers"); 1543 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>"); 1544