File Index
Files and directories
Sign in
FILE

usbmisc_imx.c

File preview with syntax highlighting.

linux-6.19.14/drivers/usb/chipidea/usbmisc_imx.c C
   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
 171struct 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
 192struct imx_usbmisc {
 193	void __iomem *base;
 194	void __iomem *blkctl;
 195	spinlock_t lock;
 196	const struct usbmisc_ops *ops;
 197};
 198
 199static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data);
 200
 201static 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
 250static 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
 279static 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
 310static 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
 410static 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
 423static 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
 450static 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
 505static 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
 526static 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
 550static 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
 578static 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
 613static 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
 633static 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
 653static 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
 674static int usbmisc_s32g2_init(struct imx_usbmisc_data *data)
 675{
 676	return usbmisc_s32g_init(data, S32G_UCMALLBE);
 677}
 678
 679static int usbmisc_s32g3_init(struct imx_usbmisc_data *data)
 680{
 681	return usbmisc_s32g_init(data, 0);
 682}
 683
 684static 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
 707static 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
 780static 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
 826static 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
 851static 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
 894static 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 */
 931static 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
 974static 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
1001static 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
1065static 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
1093static 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
1112static 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
1131static int usbmisc_s32g_power_lost_check(struct imx_usbmisc_data *data)
1132{
1133	return 1;
1134}
1135
1136static 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
1152static 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
1174static const struct usbmisc_ops imx25_usbmisc_ops = {
1175	.init = usbmisc_imx25_init,
1176	.post = usbmisc_imx25_post,
1177};
1178
1179static const struct usbmisc_ops imx27_usbmisc_ops = {
1180	.init = usbmisc_imx27_init,
1181};
1182
1183static const struct usbmisc_ops imx51_usbmisc_ops = {
1184	.init = usbmisc_imx53_init,
1185};
1186
1187static const struct usbmisc_ops imx53_usbmisc_ops = {
1188	.init = usbmisc_imx53_init,
1189};
1190
1191static 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
1198static const struct usbmisc_ops vf610_usbmisc_ops = {
1199	.init = usbmisc_vf610_init,
1200};
1201
1202static 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
1210static 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
1219static 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
1227static const struct usbmisc_ops imx94_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	.vbus_comparator_on = usbmisc_imx7d_vbus_comparator_on,
1233};
1234
1235static const struct usbmisc_ops imx95_usbmisc_ops = {
1236	.init = usbmisc_imx7d_init,
1237	.set_wakeup = usbmisc_imx95_set_wakeup,
1238	.charger_detection = imx7d_charger_detection,
1239	.power_lost_check = usbmisc_imx7d_power_lost_check,
1240	.pullup = usbmisc_imx7d_pullup,
1241	.vbus_comparator_on = usbmisc_imx7d_vbus_comparator_on,
1242};
1243
1244static const struct usbmisc_ops s32g2_usbmisc_ops = {
1245	.init = usbmisc_s32g2_init,
1246	.set_wakeup = usbmisc_s32g_set_wakeup,
1247	.power_lost_check = usbmisc_s32g_power_lost_check,
1248};
1249
1250static const struct usbmisc_ops s32g3_usbmisc_ops = {
1251	.init = usbmisc_s32g3_init,
1252	.set_wakeup = usbmisc_s32g_set_wakeup,
1253	.power_lost_check = usbmisc_s32g_power_lost_check,
1254};
1255
1256static inline bool is_imx53_usbmisc(struct imx_usbmisc_data *data)
1257{
1258	struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
1259
1260	return usbmisc->ops == &imx53_usbmisc_ops;
1261}
1262
1263int imx_usbmisc_init(struct imx_usbmisc_data *data)
1264{
1265	struct imx_usbmisc *usbmisc;
1266
1267	if (!data)
1268		return 0;
1269
1270	usbmisc = dev_get_drvdata(data->dev);
1271	if (!usbmisc->ops->init)
1272		return 0;
1273	return usbmisc->ops->init(data);
1274}
1275EXPORT_SYMBOL_GPL(imx_usbmisc_init);
1276
1277int imx_usbmisc_init_post(struct imx_usbmisc_data *data)
1278{
1279	struct imx_usbmisc *usbmisc;
1280	int ret = 0;
1281
1282	if (!data)
1283		return 0;
1284
1285	usbmisc = dev_get_drvdata(data->dev);
1286	if (usbmisc->ops->post)
1287		ret = usbmisc->ops->post(data);
1288	if (ret) {
1289		dev_err(data->dev, "post init failed, ret=%d\n", ret);
1290		return ret;
1291	}
1292
1293	if (usbmisc->ops->set_wakeup)
1294		ret = usbmisc->ops->set_wakeup(data, false);
1295	if (ret) {
1296		dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret);
1297		return ret;
1298	}
1299
1300	return 0;
1301}
1302EXPORT_SYMBOL_GPL(imx_usbmisc_init_post);
1303
1304int imx_usbmisc_hsic_set_connect(struct imx_usbmisc_data *data)
1305{
1306	struct imx_usbmisc *usbmisc;
1307
1308	if (!data)
1309		return 0;
1310
1311	usbmisc = dev_get_drvdata(data->dev);
1312	if (!usbmisc->ops->hsic_set_connect || !data->hsic)
1313		return 0;
1314	return usbmisc->ops->hsic_set_connect(data);
1315}
1316EXPORT_SYMBOL_GPL(imx_usbmisc_hsic_set_connect);
1317
1318int imx_usbmisc_charger_detection(struct imx_usbmisc_data *data, bool connect)
1319{
1320	struct imx_usbmisc *usbmisc;
1321	struct usb_phy *usb_phy;
1322	int ret = 0;
1323
1324	if (!data)
1325		return -EINVAL;
1326
1327	usbmisc = dev_get_drvdata(data->dev);
1328	usb_phy = data->usb_phy;
1329	if (!usbmisc->ops->charger_detection)
1330		return -ENOTSUPP;
1331
1332	if (connect) {
1333		ret = usbmisc->ops->charger_detection(data);
1334		if (ret) {
1335			dev_err(data->dev,
1336					"Error occurs during detection: %d\n",
1337					ret);
1338			usb_phy->chg_state = USB_CHARGER_ABSENT;
1339		} else {
1340			usb_phy->chg_state = USB_CHARGER_PRESENT;
1341		}
1342	} else {
1343		usb_phy->chg_state = USB_CHARGER_ABSENT;
1344		usb_phy->chg_type = UNKNOWN_TYPE;
1345	}
1346	return ret;
1347}
1348EXPORT_SYMBOL_GPL(imx_usbmisc_charger_detection);
1349
1350int imx_usbmisc_pullup(struct imx_usbmisc_data *data, bool on)
1351{
1352	struct imx_usbmisc *usbmisc;
1353
1354	if (!data)
1355		return 0;
1356
1357	usbmisc = dev_get_drvdata(data->dev);
1358	if (usbmisc->ops->pullup)
1359		usbmisc->ops->pullup(data, on);
1360
1361	return 0;
1362}
1363EXPORT_SYMBOL_GPL(imx_usbmisc_pullup);
1364
1365int imx_usbmisc_suspend(struct imx_usbmisc_data *data, bool wakeup)
1366{
1367	struct imx_usbmisc *usbmisc;
1368	int ret = 0;
1369
1370	if (!data)
1371		return 0;
1372
1373	usbmisc = dev_get_drvdata(data->dev);
1374
1375	if (usbmisc->ops->vbus_comparator_on)
1376		usbmisc->ops->vbus_comparator_on(data, false);
1377
1378	if (wakeup && usbmisc->ops->set_wakeup)
1379		ret = usbmisc->ops->set_wakeup(data, true);
1380	if (ret) {
1381		dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret);
1382		return ret;
1383	}
1384
1385	if (usbmisc->ops->hsic_set_clk && data->hsic)
1386		ret = usbmisc->ops->hsic_set_clk(data, false);
1387	if (ret) {
1388		dev_err(data->dev, "hsic_set_clk failed, ret=%d\n", ret);
1389		return ret;
1390	}
1391
1392	return ret;
1393}
1394EXPORT_SYMBOL_GPL(imx_usbmisc_suspend);
1395
1396int imx_usbmisc_resume(struct imx_usbmisc_data *data, bool wakeup)
1397{
1398	struct imx_usbmisc *usbmisc;
1399	int ret = 0;
1400
1401	if (!data)
1402		return 0;
1403
1404	usbmisc = dev_get_drvdata(data->dev);
1405
1406	if (usbmisc->ops->power_lost_check)
1407		ret = usbmisc->ops->power_lost_check(data);
1408	if (ret > 0) {
1409		/* re-init if resume from power lost */
1410		ret = imx_usbmisc_init(data);
1411		if (ret) {
1412			dev_err(data->dev, "re-init failed, ret=%d\n", ret);
1413			return ret;
1414		}
1415	}
1416
1417	if (wakeup && usbmisc->ops->set_wakeup)
1418		ret = usbmisc->ops->set_wakeup(data, false);
1419	if (ret) {
1420		dev_err(data->dev, "set_wakeup failed, ret=%d\n", ret);
1421		return ret;
1422	}
1423
1424	if (usbmisc->ops->hsic_set_clk && data->hsic)
1425		ret = usbmisc->ops->hsic_set_clk(data, true);
1426	if (ret) {
1427		dev_err(data->dev, "hsic_set_clk failed, ret=%d\n", ret);
1428		goto hsic_set_clk_fail;
1429	}
1430
1431	if (usbmisc->ops->vbus_comparator_on)
1432		usbmisc->ops->vbus_comparator_on(data, true);
1433
1434	return 0;
1435
1436hsic_set_clk_fail:
1437	if (wakeup && usbmisc->ops->set_wakeup)
1438		usbmisc->ops->set_wakeup(data, true);
1439	return ret;
1440}
1441EXPORT_SYMBOL_GPL(imx_usbmisc_resume);
1442
1443static const struct of_device_id usbmisc_imx_dt_ids[] = {
1444	{
1445		.compatible = "fsl,imx25-usbmisc",
1446		.data = &imx25_usbmisc_ops,
1447	},
1448	{
1449		.compatible = "fsl,imx35-usbmisc",
1450		.data = &imx25_usbmisc_ops,
1451	},
1452	{
1453		.compatible = "fsl,imx27-usbmisc",
1454		.data = &imx27_usbmisc_ops,
1455	},
1456	{
1457		.compatible = "fsl,imx51-usbmisc",
1458		.data = &imx51_usbmisc_ops,
1459	},
1460	{
1461		.compatible = "fsl,imx53-usbmisc",
1462		.data = &imx53_usbmisc_ops,
1463	},
1464	{
1465		.compatible = "fsl,imx6q-usbmisc",
1466		.data = &imx6q_usbmisc_ops,
1467	},
1468	{
1469		.compatible = "fsl,vf610-usbmisc",
1470		.data = &vf610_usbmisc_ops,
1471	},
1472	{
1473		.compatible = "fsl,imx6sx-usbmisc",
1474		.data = &imx6sx_usbmisc_ops,
1475	},
1476	{
1477		.compatible = "fsl,imx6ul-usbmisc",
1478		.data = &imx6sx_usbmisc_ops,
1479	},
1480	{
1481		.compatible = "fsl,imx7d-usbmisc",
1482		.data = &imx7d_usbmisc_ops,
1483	},
1484	{
1485		.compatible = "fsl,imx7ulp-usbmisc",
1486		.data = &imx7ulp_usbmisc_ops,
1487	},
1488	{
1489		.compatible = "fsl,imx8ulp-usbmisc",
1490		.data = &imx7ulp_usbmisc_ops,
1491	},
1492	{
1493		.compatible = "fsl,imx94-usbmisc",
1494		.data = &imx94_usbmisc_ops,
1495	},
1496	{
1497		.compatible = "fsl,imx95-usbmisc",
1498		.data = &imx95_usbmisc_ops,
1499	},
1500	{
1501		.compatible = "nxp,s32g2-usbmisc",
1502		.data = &s32g2_usbmisc_ops,
1503	},
1504	{
1505		.compatible = "nxp,s32g3-usbmisc",
1506		.data = &s32g3_usbmisc_ops,
1507	},
1508	{ /* sentinel */ }
1509};
1510MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids);
1511
1512static int usbmisc_imx_probe(struct platform_device *pdev)
1513{
1514	struct imx_usbmisc *data;
1515	struct resource *res;
1516
1517	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
1518	if (!data)
1519		return -ENOMEM;
1520
1521	spin_lock_init(&data->lock);
1522
1523	data->base = devm_platform_ioremap_resource(pdev, 0);
1524	if (IS_ERR(data->base))
1525		return PTR_ERR(data->base);
1526
1527	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1528	if (res) {
1529		data->blkctl = devm_ioremap_resource(&pdev->dev, res);
1530		if (IS_ERR(data->blkctl))
1531			return PTR_ERR(data->blkctl);
1532	} else if (device_is_compatible(&pdev->dev, "fsl,imx95-usbmisc")) {
1533		dev_warn(&pdev->dev, "wakeup setting is missing\n");
1534	}
1535
1536	data->ops = of_device_get_match_data(&pdev->dev);
1537	platform_set_drvdata(pdev, data);
1538
1539	return 0;
1540}
1541
1542static struct platform_driver usbmisc_imx_driver = {
1543	.probe = usbmisc_imx_probe,
1544	.driver = {
1545		.name = "usbmisc_imx",
1546		.of_match_table = usbmisc_imx_dt_ids,
1547	 },
1548};
1549
1550module_platform_driver(usbmisc_imx_driver);
1551
1552MODULE_ALIAS("platform:usbmisc-imx");
1553MODULE_LICENSE("GPL");
1554MODULE_DESCRIPTION("driver for imx usb non-core registers");
1555MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");
~/ Read-only file preview.