1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2012 Freescale Semiconductor, Inc. 4 */ 5 6 #include <linux/module.h> 7 #include <linux/of_platform.h> 8 #include <linux/err.h> 9 #include <linux/io.h> 10 #include <linux/delay.h> 11 12 #include "ci_hdrc_imx.h" 13 14 #define MX25_USB_PHY_CTRL_OFFSET 0x08 15 #define MX25_BM_EXTERNAL_VBUS_DIVIDER BIT(23) 16 17 #define MX25_EHCI_INTERFACE_SINGLE_UNI (2 << 0) 18 #define MX25_EHCI_INTERFACE_DIFF_UNI (0 << 0) 19 #define MX25_EHCI_INTERFACE_MASK (0xf) 20 21 #define MX25_OTG_SIC_SHIFT 29 22 #define MX25_OTG_SIC_MASK (0x3 << MX25_OTG_SIC_SHIFT) 23 #define MX25_OTG_PM_BIT BIT(24) 24 #define MX25_OTG_PP_BIT BIT(11) 25 #define MX25_OTG_OCPOL_BIT BIT(3) 26 27 #define MX25_H1_SIC_SHIFT 21 28 #define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT) 29 #define MX25_H1_PP_BIT BIT(18) 30 #define MX25_H1_PM_BIT BIT(16) 31 #define MX25_H1_IPPUE_UP_BIT BIT(7) 32 #define MX25_H1_IPPUE_DOWN_BIT BIT(6) 33 #define MX25_H1_TLL_BIT BIT(5) 34 #define MX25_H1_USBTE_BIT BIT(4) 35 #define MX25_H1_OCPOL_BIT BIT(2) 36 37 #define MX27_H1_PM_BIT BIT(8) 38 #define MX27_H2_PM_BIT BIT(16) 39 #define MX27_OTG_PM_BIT BIT(24) 40 41 #define MX53_USB_OTG_PHY_CTRL_0_OFFSET 0x08 42 #define MX53_USB_OTG_PHY_CTRL_1_OFFSET 0x0c 43 #define MX53_USB_CTRL_1_OFFSET 0x10 44 #define MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_MASK (0x11 << 2) 45 #define MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_ULPI BIT(2) 46 #define MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_MASK (0x11 << 6) 47 #define MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_ULPI BIT(6) 48 #define MX53_USB_UH2_CTRL_OFFSET 0x14 49 #define MX53_USB_UH3_CTRL_OFFSET 0x18 50 #define MX53_USB_CLKONOFF_CTRL_OFFSET 0x24 51 #define MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF BIT(21) 52 #define MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF BIT(22) 53 #define MX53_BM_OVER_CUR_DIS_H1 BIT(5) 54 #define MX53_BM_OVER_CUR_DIS_OTG BIT(8) 55 #define MX53_BM_OVER_CUR_DIS_UHx BIT(30) 56 #define MX53_USB_CTRL_1_UH2_ULPI_EN BIT(26) 57 #define MX53_USB_CTRL_1_UH3_ULPI_EN BIT(27) 58 #define MX53_USB_UHx_CTRL_WAKE_UP_EN BIT(7) 59 #define MX53_USB_UHx_CTRL_ULPI_INT_EN BIT(8) 60 #define MX53_USB_PHYCTRL1_PLLDIV_MASK 0x3 61 #define MX53_USB_PLL_DIV_24_MHZ 0x01 62 63 #define MX6_BM_NON_BURST_SETTING BIT(1) 64 #define MX6_BM_OVER_CUR_DIS BIT(7) 65 #define MX6_BM_OVER_CUR_POLARITY BIT(8) 66 #define MX6_BM_PWR_POLARITY BIT(9) 67 #define MX6_BM_WAKEUP_ENABLE BIT(10) 68 #define MX6_BM_UTMI_ON_CLOCK BIT(13) 69 #define MX6_BM_ID_WAKEUP BIT(16) 70 #define MX6_BM_VBUS_WAKEUP BIT(17) 71 #define MX6SX_BM_DPDM_WAKEUP_EN BIT(29) 72 #define MX6_BM_WAKEUP_INTR BIT(31) 73 74 #define MX6_USB_HSIC_CTRL_OFFSET 0x10 75 /* Send resume signal without 480Mhz PHY clock */ 76 #define MX6SX_BM_HSIC_AUTO_RESUME BIT(23) 77 /* set before portsc.suspendM = 1 */ 78 #define MX6_BM_HSIC_DEV_CONN BIT(21) 79 /* HSIC enable */ 80 #define MX6_BM_HSIC_EN BIT(12) 81 /* Force HSIC module 480M clock on, even when in Host is in suspend mode */ 82 #define MX6_BM_HSIC_CLK_ON BIT(11) 83 84 #define MX6_USB_OTG1_PHY_CTRL 0x18 85 /* For imx6dql, it is host-only controller, for later imx6, it is otg's */ 86 #define MX6_USB_OTG2_PHY_CTRL 0x1c 87 #define MX6SX_USB_VBUS_WAKEUP_SOURCE(v) (v << 8) 88 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_VBUS MX6SX_USB_VBUS_WAKEUP_SOURCE(0) 89 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_AVALID MX6SX_USB_VBUS_WAKEUP_SOURCE(1) 90 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID MX6SX_USB_VBUS_WAKEUP_SOURCE(2) 91 #define MX6SX_USB_VBUS_WAKEUP_SOURCE_SESS_END MX6SX_USB_VBUS_WAKEUP_SOURCE(3) 92 93 #define VF610_OVER_CUR_DIS BIT(7) 94 95 #define MX7D_USBNC_USB_CTRL2 0x4 96 #define MX7D_USB_VBUS_WAKEUP_SOURCE_MASK 0x3 97 #define MX7D_USB_VBUS_WAKEUP_SOURCE(v) (v << 0) 98 #define MX7D_USB_VBUS_WAKEUP_SOURCE_VBUS MX7D_USB_VBUS_WAKEUP_SOURCE(0) 99 #define MX7D_USB_VBUS_WAKEUP_SOURCE_AVALID MX7D_USB_VBUS_WAKEUP_SOURCE(1) 100 #define MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID MX7D_USB_VBUS_WAKEUP_SOURCE(2) 101 #define MX7D_USB_VBUS_WAKEUP_SOURCE_SESS_END MX7D_USB_VBUS_WAKEUP_SOURCE(3) 102 103 struct usbmisc_ops { 104 /* It's called once when probe a usb device */ 105 int (*init)(struct imx_usbmisc_data *data); 106 /* It's called once after adding a usb device */ 107 int (*post)(struct imx_usbmisc_data *data); 108 /* It's called when we need to enable/disable usb wakeup */ 109 int (*set_wakeup)(struct imx_usbmisc_data *data, bool enabled); 110 /* It's called before setting portsc.suspendM */ 111 int (*hsic_set_connect)(struct imx_usbmisc_data *data); 112 /* It's called during suspend/resume */ 113 int (*hsic_set_clk)(struct imx_usbmisc_data *data, bool enabled); 114 }; 115 116 struct imx_usbmisc { 117 void __iomem *base; 118 spinlock_t lock; 119 const struct usbmisc_ops *ops; 120 }; 121 122 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data); 123 124 static int usbmisc_imx25_init(struct imx_usbmisc_data *data) 125 { 126 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 127 unsigned long flags; 128 u32 val = 0; 129 130 if (data->index > 1) 131 return -EINVAL; 132 133 spin_lock_irqsave(&usbmisc->lock, flags); 134 switch (data->index) { 135 case 0: 136 val = readl(usbmisc->base); 137 val &= ~(MX25_OTG_SIC_MASK | MX25_OTG_PP_BIT); 138 val |= (MX25_EHCI_INTERFACE_DIFF_UNI & MX25_EHCI_INTERFACE_MASK) << MX25_OTG_SIC_SHIFT; 139 val |= (MX25_OTG_PM_BIT | MX25_OTG_OCPOL_BIT); 140 141 /* 142 * If the polarity is not configured assume active high for 143 * historical reasons. 144 */ 145 if (data->oc_pol_configured && data->oc_pol_active_low) 146 val &= ~MX25_OTG_OCPOL_BIT; 147 148 writel(val, usbmisc->base); 149 break; 150 case 1: 151 val = readl(usbmisc->base); 152 val &= ~(MX25_H1_SIC_MASK | MX25_H1_PP_BIT | MX25_H1_IPPUE_UP_BIT); 153 val |= (MX25_EHCI_INTERFACE_SINGLE_UNI & MX25_EHCI_INTERFACE_MASK) << MX25_H1_SIC_SHIFT; 154 val |= (MX25_H1_PM_BIT | MX25_H1_OCPOL_BIT | MX25_H1_TLL_BIT | 155 MX25_H1_USBTE_BIT | MX25_H1_IPPUE_DOWN_BIT); 156 157 /* 158 * If the polarity is not configured assume active high for 159 * historical reasons. 160 */ 161 if (data->oc_pol_configured && data->oc_pol_active_low) 162 val &= ~MX25_H1_OCPOL_BIT; 163 164 writel(val, usbmisc->base); 165 166 break; 167 } 168 spin_unlock_irqrestore(&usbmisc->lock, flags); 169 170 return 0; 171 } 172 173 static int usbmisc_imx25_post(struct imx_usbmisc_data *data) 174 { 175 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 176 void __iomem *reg; 177 unsigned long flags; 178 u32 val; 179 180 if (data->index > 2) 181 return -EINVAL; 182 183 if (data->index) 184 return 0; 185 186 spin_lock_irqsave(&usbmisc->lock, flags); 187 reg = usbmisc->base + MX25_USB_PHY_CTRL_OFFSET; 188 val = readl(reg); 189 190 if (data->evdo) 191 val |= MX25_BM_EXTERNAL_VBUS_DIVIDER; 192 else 193 val &= ~MX25_BM_EXTERNAL_VBUS_DIVIDER; 194 195 writel(val, reg); 196 spin_unlock_irqrestore(&usbmisc->lock, flags); 197 usleep_range(5000, 10000); /* needed to stabilize voltage */ 198 199 return 0; 200 } 201 202 static int usbmisc_imx27_init(struct imx_usbmisc_data *data) 203 { 204 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 205 unsigned long flags; 206 u32 val; 207 208 switch (data->index) { 209 case 0: 210 val = MX27_OTG_PM_BIT; 211 break; 212 case 1: 213 val = MX27_H1_PM_BIT; 214 break; 215 case 2: 216 val = MX27_H2_PM_BIT; 217 break; 218 default: 219 return -EINVAL; 220 } 221 222 spin_lock_irqsave(&usbmisc->lock, flags); 223 if (data->disable_oc) 224 val = readl(usbmisc->base) | val; 225 else 226 val = readl(usbmisc->base) & ~val; 227 writel(val, usbmisc->base); 228 spin_unlock_irqrestore(&usbmisc->lock, flags); 229 230 return 0; 231 } 232 233 static int usbmisc_imx53_init(struct imx_usbmisc_data *data) 234 { 235 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 236 void __iomem *reg = NULL; 237 unsigned long flags; 238 u32 val = 0; 239 240 if (data->index > 3) 241 return -EINVAL; 242 243 /* Select a 24 MHz reference clock for the PHY */ 244 val = readl(usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET); 245 val &= ~MX53_USB_PHYCTRL1_PLLDIV_MASK; 246 val |= MX53_USB_PLL_DIV_24_MHZ; 247 writel(val, usbmisc->base + MX53_USB_OTG_PHY_CTRL_1_OFFSET); 248 249 spin_lock_irqsave(&usbmisc->lock, flags); 250 251 switch (data->index) { 252 case 0: 253 if (data->disable_oc) { 254 reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET; 255 val = readl(reg) | MX53_BM_OVER_CUR_DIS_OTG; 256 writel(val, reg); 257 } 258 break; 259 case 1: 260 if (data->disable_oc) { 261 reg = usbmisc->base + MX53_USB_OTG_PHY_CTRL_0_OFFSET; 262 val = readl(reg) | MX53_BM_OVER_CUR_DIS_H1; 263 writel(val, reg); 264 } 265 break; 266 case 2: 267 if (data->ulpi) { 268 /* set USBH2 into ULPI-mode. */ 269 reg = usbmisc->base + MX53_USB_CTRL_1_OFFSET; 270 val = readl(reg) | MX53_USB_CTRL_1_UH2_ULPI_EN; 271 /* select ULPI clock */ 272 val &= ~MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_MASK; 273 val |= MX53_USB_CTRL_1_H2_XCVR_CLK_SEL_ULPI; 274 writel(val, reg); 275 /* Set interrupt wake up enable */ 276 reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET; 277 val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN 278 | MX53_USB_UHx_CTRL_ULPI_INT_EN; 279 writel(val, reg); 280 if (is_imx53_usbmisc(data)) { 281 /* Disable internal 60Mhz clock */ 282 reg = usbmisc->base + 283 MX53_USB_CLKONOFF_CTRL_OFFSET; 284 val = readl(reg) | 285 MX53_USB_CLKONOFF_CTRL_H2_INT60CKOFF; 286 writel(val, reg); 287 } 288 289 } 290 if (data->disable_oc) { 291 reg = usbmisc->base + MX53_USB_UH2_CTRL_OFFSET; 292 val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx; 293 writel(val, reg); 294 } 295 break; 296 case 3: 297 if (data->ulpi) { 298 /* set USBH3 into ULPI-mode. */ 299 reg = usbmisc->base + MX53_USB_CTRL_1_OFFSET; 300 val = readl(reg) | MX53_USB_CTRL_1_UH3_ULPI_EN; 301 /* select ULPI clock */ 302 val &= ~MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_MASK; 303 val |= MX53_USB_CTRL_1_H3_XCVR_CLK_SEL_ULPI; 304 writel(val, reg); 305 /* Set interrupt wake up enable */ 306 reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET; 307 val = readl(reg) | MX53_USB_UHx_CTRL_WAKE_UP_EN 308 | MX53_USB_UHx_CTRL_ULPI_INT_EN; 309 writel(val, reg); 310 311 if (is_imx53_usbmisc(data)) { 312 /* Disable internal 60Mhz clock */ 313 reg = usbmisc->base + 314 MX53_USB_CLKONOFF_CTRL_OFFSET; 315 val = readl(reg) | 316 MX53_USB_CLKONOFF_CTRL_H3_INT60CKOFF; 317 writel(val, reg); 318 } 319 } 320 if (data->disable_oc) { 321 reg = usbmisc->base + MX53_USB_UH3_CTRL_OFFSET; 322 val = readl(reg) | MX53_BM_OVER_CUR_DIS_UHx; 323 writel(val, reg); 324 } 325 break; 326 } 327 328 spin_unlock_irqrestore(&usbmisc->lock, flags); 329 330 return 0; 331 } 332 333 static int usbmisc_imx6q_set_wakeup 334 (struct imx_usbmisc_data *data, bool enabled) 335 { 336 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 337 unsigned long flags; 338 u32 val; 339 u32 wakeup_setting = (MX6_BM_WAKEUP_ENABLE | 340 MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP); 341 int ret = 0; 342 343 if (data->index > 3) 344 return -EINVAL; 345 346 spin_lock_irqsave(&usbmisc->lock, flags); 347 val = readl(usbmisc->base + data->index * 4); 348 if (enabled) { 349 val |= wakeup_setting; 350 } else { 351 if (val & MX6_BM_WAKEUP_INTR) 352 pr_debug("wakeup int at ci_hdrc.%d\n", data->index); 353 val &= ~wakeup_setting; 354 } 355 writel(val, usbmisc->base + data->index * 4); 356 spin_unlock_irqrestore(&usbmisc->lock, flags); 357 358 return ret; 359 } 360 361 static int usbmisc_imx6q_init(struct imx_usbmisc_data *data) 362 { 363 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 364 unsigned long flags; 365 u32 reg; 366 367 if (data->index > 3) 368 return -EINVAL; 369 370 spin_lock_irqsave(&usbmisc->lock, flags); 371 372 reg = readl(usbmisc->base + data->index * 4); 373 if (data->disable_oc) { 374 reg |= MX6_BM_OVER_CUR_DIS; 375 } else { 376 reg &= ~MX6_BM_OVER_CUR_DIS; 377 378 /* 379 * If the polarity is not configured keep it as setup by the 380 * bootloader. 381 */ 382 if (data->oc_pol_configured && data->oc_pol_active_low) 383 reg |= MX6_BM_OVER_CUR_POLARITY; 384 else if (data->oc_pol_configured) 385 reg &= ~MX6_BM_OVER_CUR_POLARITY; 386 } 387 /* If the polarity is not set keep it as setup by the bootlader */ 388 if (data->pwr_pol == 1) 389 reg |= MX6_BM_PWR_POLARITY; 390 writel(reg, usbmisc->base + data->index * 4); 391 392 /* SoC non-burst setting */ 393 reg = readl(usbmisc->base + data->index * 4); 394 writel(reg | MX6_BM_NON_BURST_SETTING, 395 usbmisc->base + data->index * 4); 396 397 /* For HSIC controller */ 398 if (data->hsic) { 399 reg = readl(usbmisc->base + data->index * 4); 400 writel(reg | MX6_BM_UTMI_ON_CLOCK, 401 usbmisc->base + data->index * 4); 402 reg = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET 403 + (data->index - 2) * 4); 404 reg |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON; 405 writel(reg, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET 406 + (data->index - 2) * 4); 407 } 408 409 spin_unlock_irqrestore(&usbmisc->lock, flags); 410 411 usbmisc_imx6q_set_wakeup(data, false); 412 413 return 0; 414 } 415 416 static int usbmisc_imx6_hsic_get_reg_offset(struct imx_usbmisc_data *data) 417 { 418 int offset, ret = 0; 419 420 if (data->index == 2 || data->index == 3) { 421 offset = (data->index - 2) * 4; 422 } else if (data->index == 0) { 423 /* 424 * For SoCs like i.MX7D and later, each USB controller has 425 * its own non-core register region. For SoCs before i.MX7D, 426 * the first two USB controllers are non-HSIC controllers. 427 */ 428 offset = 0; 429 } else { 430 dev_err(data->dev, "index is error for usbmisc\n"); 431 ret = -EINVAL; 432 } 433 434 return ret ? ret : offset; 435 } 436 437 static int usbmisc_imx6_hsic_set_connect(struct imx_usbmisc_data *data) 438 { 439 unsigned long flags; 440 u32 val; 441 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 442 int offset; 443 444 spin_lock_irqsave(&usbmisc->lock, flags); 445 offset = usbmisc_imx6_hsic_get_reg_offset(data); 446 if (offset < 0) { 447 spin_unlock_irqrestore(&usbmisc->lock, flags); 448 return offset; 449 } 450 451 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); 452 if (!(val & MX6_BM_HSIC_DEV_CONN)) 453 writel(val | MX6_BM_HSIC_DEV_CONN, 454 usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); 455 456 spin_unlock_irqrestore(&usbmisc->lock, flags); 457 458 return 0; 459 } 460 461 static int usbmisc_imx6_hsic_set_clk(struct imx_usbmisc_data *data, bool on) 462 { 463 unsigned long flags; 464 u32 val; 465 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 466 int offset; 467 468 spin_lock_irqsave(&usbmisc->lock, flags); 469 offset = usbmisc_imx6_hsic_get_reg_offset(data); 470 if (offset < 0) { 471 spin_unlock_irqrestore(&usbmisc->lock, flags); 472 return offset; 473 } 474 475 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); 476 val |= MX6_BM_HSIC_EN | MX6_BM_HSIC_CLK_ON; 477 if (on) 478 val |= MX6_BM_HSIC_CLK_ON; 479 else 480 val &= ~MX6_BM_HSIC_CLK_ON; 481 482 writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET + offset); 483 spin_unlock_irqrestore(&usbmisc->lock, flags); 484 485 return 0; 486 } 487 488 489 static int usbmisc_imx6sx_init(struct imx_usbmisc_data *data) 490 { 491 void __iomem *reg = NULL; 492 unsigned long flags; 493 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 494 u32 val; 495 496 usbmisc_imx6q_init(data); 497 498 if (data->index == 0 || data->index == 1) { 499 reg = usbmisc->base + MX6_USB_OTG1_PHY_CTRL + data->index * 4; 500 spin_lock_irqsave(&usbmisc->lock, flags); 501 /* Set vbus wakeup source as bvalid */ 502 val = readl(reg); 503 writel(val | MX6SX_USB_VBUS_WAKEUP_SOURCE_BVALID, reg); 504 /* 505 * Disable dp/dm wakeup in device mode when vbus is 506 * not there. 507 */ 508 val = readl(usbmisc->base + data->index * 4); 509 writel(val & ~MX6SX_BM_DPDM_WAKEUP_EN, 510 usbmisc->base + data->index * 4); 511 spin_unlock_irqrestore(&usbmisc->lock, flags); 512 } 513 514 /* For HSIC controller */ 515 if (data->hsic) { 516 val = readl(usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); 517 val |= MX6SX_BM_HSIC_AUTO_RESUME; 518 writel(val, usbmisc->base + MX6_USB_HSIC_CTRL_OFFSET); 519 } 520 521 return 0; 522 } 523 524 static int usbmisc_vf610_init(struct imx_usbmisc_data *data) 525 { 526 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 527 u32 reg; 528 529 /* 530 * Vybrid only has one misc register set, but in two different 531 * areas. These is reflected in two instances of this driver. 532 */ 533 if (data->index >= 1) 534 return -EINVAL; 535 536 if (data->disable_oc) { 537 reg = readl(usbmisc->base); 538 writel(reg | VF610_OVER_CUR_DIS, usbmisc->base); 539 } 540 541 return 0; 542 } 543 544 static int usbmisc_imx7d_set_wakeup 545 (struct imx_usbmisc_data *data, bool enabled) 546 { 547 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 548 unsigned long flags; 549 u32 val; 550 u32 wakeup_setting = (MX6_BM_WAKEUP_ENABLE | 551 MX6_BM_VBUS_WAKEUP | MX6_BM_ID_WAKEUP); 552 553 spin_lock_irqsave(&usbmisc->lock, flags); 554 val = readl(usbmisc->base); 555 if (enabled) { 556 writel(val | wakeup_setting, usbmisc->base); 557 } else { 558 if (val & MX6_BM_WAKEUP_INTR) 559 dev_dbg(data->dev, "wakeup int\n"); 560 writel(val & ~wakeup_setting, usbmisc->base); 561 } 562 spin_unlock_irqrestore(&usbmisc->lock, flags); 563 564 return 0; 565 } 566 567 static int usbmisc_imx7d_init(struct imx_usbmisc_data *data) 568 { 569 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 570 unsigned long flags; 571 u32 reg; 572 573 if (data->index >= 1) 574 return -EINVAL; 575 576 spin_lock_irqsave(&usbmisc->lock, flags); 577 reg = readl(usbmisc->base); 578 if (data->disable_oc) { 579 reg |= MX6_BM_OVER_CUR_DIS; 580 } else { 581 reg &= ~MX6_BM_OVER_CUR_DIS; 582 583 /* 584 * If the polarity is not configured keep it as setup by the 585 * bootloader. 586 */ 587 if (data->oc_pol_configured && data->oc_pol_active_low) 588 reg |= MX6_BM_OVER_CUR_POLARITY; 589 else if (data->oc_pol_configured) 590 reg &= ~MX6_BM_OVER_CUR_POLARITY; 591 } 592 /* If the polarity is not set keep it as setup by the bootlader */ 593 if (data->pwr_pol == 1) 594 reg |= MX6_BM_PWR_POLARITY; 595 writel(reg, usbmisc->base); 596 597 reg = readl(usbmisc->base + MX7D_USBNC_USB_CTRL2); 598 reg &= ~MX7D_USB_VBUS_WAKEUP_SOURCE_MASK; 599 writel(reg | MX7D_USB_VBUS_WAKEUP_SOURCE_BVALID, 600 usbmisc->base + MX7D_USBNC_USB_CTRL2); 601 602 spin_unlock_irqrestore(&usbmisc->lock, flags); 603 604 usbmisc_imx7d_set_wakeup(data, false); 605 606 return 0; 607 } 608 609 static const struct usbmisc_ops imx25_usbmisc_ops = { 610 .init = usbmisc_imx25_init, 611 .post = usbmisc_imx25_post, 612 }; 613 614 static const struct usbmisc_ops imx27_usbmisc_ops = { 615 .init = usbmisc_imx27_init, 616 }; 617 618 static const struct usbmisc_ops imx51_usbmisc_ops = { 619 .init = usbmisc_imx53_init, 620 }; 621 622 static const struct usbmisc_ops imx53_usbmisc_ops = { 623 .init = usbmisc_imx53_init, 624 }; 625 626 static const struct usbmisc_ops imx6q_usbmisc_ops = { 627 .set_wakeup = usbmisc_imx6q_set_wakeup, 628 .init = usbmisc_imx6q_init, 629 .hsic_set_connect = usbmisc_imx6_hsic_set_connect, 630 .hsic_set_clk = usbmisc_imx6_hsic_set_clk, 631 }; 632 633 static const struct usbmisc_ops vf610_usbmisc_ops = { 634 .init = usbmisc_vf610_init, 635 }; 636 637 static const struct usbmisc_ops imx6sx_usbmisc_ops = { 638 .set_wakeup = usbmisc_imx6q_set_wakeup, 639 .init = usbmisc_imx6sx_init, 640 .hsic_set_connect = usbmisc_imx6_hsic_set_connect, 641 .hsic_set_clk = usbmisc_imx6_hsic_set_clk, 642 }; 643 644 static const struct usbmisc_ops imx7d_usbmisc_ops = { 645 .init = usbmisc_imx7d_init, 646 .set_wakeup = usbmisc_imx7d_set_wakeup, 647 }; 648 649 static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data) 650 { 651 struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev); 652 653 return usbmisc->ops == &imx53_usbmisc_ops; 654 } 655 656 int imx_usbmisc_init(struct imx_usbmisc_data *data) 657 { 658 struct imx_usbmisc *usbmisc; 659 660 if (!data) 661 return 0; 662 663 usbmisc = dev_get_drvdata(data->dev); 664 if (!usbmisc->ops->init) 665 return 0; 666 return usbmisc->ops->init(data); 667 } 668 EXPORT_SYMBOL_GPL(imx_usbmisc_init); 669 670 int imx_usbmisc_init_post(struct imx_usbmisc_data *data) 671 { 672 struct imx_usbmisc *usbmisc; 673 674 if (!data) 675 return 0; 676 677 usbmisc = dev_get_drvdata(data->dev); 678 if (!usbmisc->ops->post) 679 return 0; 680 return usbmisc->ops->post(data); 681 } 682 EXPORT_SYMBOL_GPL(imx_usbmisc_init_post); 683 684 int imx_usbmisc_set_wakeup(struct imx_usbmisc_data *data, bool enabled) 685 { 686 struct imx_usbmisc *usbmisc; 687 688 if (!data) 689 return 0; 690 691 usbmisc = dev_get_drvdata(data->dev); 692 if (!usbmisc->ops->set_wakeup) 693 return 0; 694 return usbmisc->ops->set_wakeup(data, enabled); 695 } 696 EXPORT_SYMBOL_GPL(imx_usbmisc_set_wakeup); 697 698 int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *data) 699 { 700 struct imx_usbmisc *usbmisc; 701 702 if (!data) 703 return 0; 704 705 usbmisc = dev_get_drvdata(data->dev); 706 if (!usbmisc->ops->hsic_set_connect || !data->hsic) 707 return 0; 708 return usbmisc->ops->hsic_set_connect(data); 709 } 710 EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_connect); 711 712 int imx_usbmisc_hsic_set_clk(struct imx_usbmisc_data *data, bool on) 713 { 714 struct imx_usbmisc *usbmisc; 715 716 if (!data) 717 return 0; 718 719 usbmisc = dev_get_drvdata(data->dev); 720 if (!usbmisc->ops->hsic_set_clk || !data->hsic) 721 return 0; 722 return usbmisc->ops->hsic_set_clk(data, on); 723 } 724 EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_clk); 725 static const struct of_device_id usbmisc_imx_dt_ids[] = { 726 { 727 .compatible = "fsl,imx25-usbmisc", 728 .data = &imx25_usbmisc_ops, 729 }, 730 { 731 .compatible = "fsl,imx35-usbmisc", 732 .data = &imx25_usbmisc_ops, 733 }, 734 { 735 .compatible = "fsl,imx27-usbmisc", 736 .data = &imx27_usbmisc_ops, 737 }, 738 { 739 .compatible = "fsl,imx51-usbmisc", 740 .data = &imx51_usbmisc_ops, 741 }, 742 { 743 .compatible = "fsl,imx53-usbmisc", 744 .data = &imx53_usbmisc_ops, 745 }, 746 { 747 .compatible = "fsl,imx6q-usbmisc", 748 .data = &imx6q_usbmisc_ops, 749 }, 750 { 751 .compatible = "fsl,vf610-usbmisc", 752 .data = &vf610_usbmisc_ops, 753 }, 754 { 755 .compatible = "fsl,imx6sx-usbmisc", 756 .data = &imx6sx_usbmisc_ops, 757 }, 758 { 759 .compatible = "fsl,imx6ul-usbmisc", 760 .data = &imx6sx_usbmisc_ops, 761 }, 762 { 763 .compatible = "fsl,imx7d-usbmisc", 764 .data = &imx7d_usbmisc_ops, 765 }, 766 { /* sentinel */ } 767 }; 768 MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids); 769 770 static int usbmisc_imx_probe(struct platform_device *pdev) 771 { 772 struct resource *res; 773 struct imx_usbmisc *data; 774 const struct of_device_id *of_id; 775 776 of_id = of_match_device(usbmisc_imx_dt_ids, &pdev->dev); 777 if (!of_id) 778 return -ENODEV; 779 780 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 781 if (!data) 782 return -ENOMEM; 783 784 spin_lock_init(&data->lock); 785 786 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 787 data->base = devm_ioremap_resource(&pdev->dev, res); 788 if (IS_ERR(data->base)) 789 return PTR_ERR(data->base); 790 791 data->ops = (const struct usbmisc_ops *)of_id->data; 792 platform_set_drvdata(pdev, data); 793 794 return 0; 795 } 796 797 static int usbmisc_imx_remove(struct platform_device *pdev) 798 { 799 return 0; 800 } 801 802 static struct platform_driver usbmisc_imx_driver = { 803 .probe = usbmisc_imx_probe, 804 .remove = usbmisc_imx_remove, 805 .driver = { 806 .name = "usbmisc_imx", 807 .of_match_table = usbmisc_imx_dt_ids, 808 }, 809 }; 810 811 module_platform_driver(usbmisc_imx_driver); 812 813 MODULE_ALIAS("platform:usbmisc-imx"); 814 MODULE_LICENSE("GPL"); 815 MODULE_DESCRIPTION("driver for imx usb non-core registers"); 816 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>"); 817