/*
 * Sets the phy clk as EXTREFCLK (XXTI) which is internal clock from clock core.
 */
static u32 samsung_usb3phy_set_refclk(struct samsung_usbphy *sphy)
{
	u32 reg;
	u32 refclk;

	refclk = sphy->ref_clk_freq;

	reg = PHYCLKRST_REFCLKSEL_EXT_REFCLK |
		PHYCLKRST_FSEL(refclk);

	switch (refclk) {
	case FSEL_CLKSEL_50M:
		reg |= (PHYCLKRST_MPLL_MULTIPLIER_50M_REF |
			PHYCLKRST_SSC_REFCLKSEL(0x00));
		break;
	case FSEL_CLKSEL_20M:
		reg |= (PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF |
			PHYCLKRST_SSC_REFCLKSEL(0x00));
		break;
	case FSEL_CLKSEL_19200K:
		reg |= (PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF |
			PHYCLKRST_SSC_REFCLKSEL(0x88));
		break;
	case FSEL_CLKSEL_24M:
	default:
		reg |= (PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF |
			PHYCLKRST_SSC_REFCLKSEL(0x88));
		break;
	}

	return reg;
}
Пример #2
0
void exynos5_usb3_phy_init(struct exynos_usb3_phy *phy)
{
	u32 reg;

	/* Reset USB 3.0 PHY */
	writel(0x0, &phy->phy_reg0);

	clrbits_le32(&phy->phy_param0,
			/* Select PHY CLK source */
			PHYPARAM0_REF_USE_PAD |
			/* Set Loss-of-Signal Detector sensitivity */
			PHYPARAM0_REF_LOSLEVEL_MASK);
	setbits_le32(&phy->phy_param0, PHYPARAM0_REF_LOSLEVEL);


	writel(0x0, &phy->phy_resume);

	/*
	 * Setting the Frame length Adj value[6:1] to default 0x20
	 * See xHCI 1.0 spec, 5.2.4
	 */
	setbits_le32(&phy->link_system,
			LINKSYSTEM_XHCI_VERSION_CONTROL |
			LINKSYSTEM_FLADJ(0x20));

	/* Set Tx De-Emphasis level */
	clrbits_le32(&phy->phy_param1, PHYPARAM1_PCS_TXDEEMPH_MASK);
	setbits_le32(&phy->phy_param1, PHYPARAM1_PCS_TXDEEMPH);

	setbits_le32(&phy->phy_batchg, PHYBATCHG_UTMI_CLKSEL);

	/* PHYTEST POWERDOWN Control */
	clrbits_le32(&phy->phy_test,
			PHYTEST_POWERDOWN_SSP |
			PHYTEST_POWERDOWN_HSP);

	/* UTMI Power Control */
	writel(PHYUTMI_OTGDISABLE, &phy->phy_utmi);

		/* Use core clock from main PLL */
	reg = PHYCLKRST_REFCLKSEL_EXT_REFCLK |
		/* Default 24Mhz crystal clock */
		PHYCLKRST_FSEL(FSEL_CLKSEL_24M) |
		PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF |
		PHYCLKRST_SSC_REFCLKSEL(0) |
		/* Force PortReset of PHY */
		PHYCLKRST_PORTRESET |
		/* Digital power supply in normal operating mode */
		PHYCLKRST_RETENABLEN |
		/* Enable ref clock for SS function */
		PHYCLKRST_REF_SSP_EN |
		/* Enable spread spectrum */
		PHYCLKRST_SSC_EN |
		/* Power down HS Bias and PLL blocks in suspend mode */
		PHYCLKRST_COMMONONN;

	writel(reg, &phy->phy_clk_rst);

	/* giving time to Phy clock to settle before resetting */
	udelay(10);

	reg &= ~PHYCLKRST_PORTRESET;
	writel(reg, &phy->phy_clk_rst);
}
void samsung_exynos_cal_dwc_usb2phy_enable(void __iomem *regs_base,
		u32 refclkfreq, enum samsung_usb_phy_type phy_type)
{
	u32 phyutmi;
	u32 phyclkrst;
	u32 hostplltune;
	u32 stdphyctrl;
	u32 otglinkctrl;
	u32 hostlinkctrl;
	u32 resume;

	stdphyctrl = readl(regs_base + SAMSUNG_PHY_STDPHYCTRL);
	stdphyctrl &= ~STDPHYCTRL_SIDDQ;
	writel(stdphyctrl, regs_base + SAMSUNG_PHY_STDPHYCTRL);
	udelay(500);

	/* USB Bypass cell clear */
	resume = readl(regs_base + SAMSUNG_RESUME);
	resume &= ~USB_BYPASSSEL;
	resume &= ~USB_BYPASSDPEN;
	resume &= ~USB_BYPASSDMEN;
	writel(resume, regs_base + SAMSUNG_RESUME);

	/* release force_sleep & force_suspend */
	phyutmi = readl(regs_base + SAMSUNG_PHYUTMI);
	phyutmi &= ~PHYUTMI_FORCESLEEP;
	phyutmi &= ~PHYUTMI_FORCESUSPEND;

	/* DP/DM Pull Down Disable */
	phyutmi &= ~PHYUTMI_DMPULLDOWN;
	phyutmi &= ~PHYUTMI_DPPULLDOWN;

	phyutmi |= PHYUTMI_DRVVBUS;
	phyutmi &= ~PHYUTMI_OTGDISABLE;
	writel(phyutmi, regs_base + SAMSUNG_PHYUTMI);

	/* Enable Common Block in suspend/sleep mode */
	phyclkrst = readl(regs_base + SAMSUNG_PHYCLKRST);
	phyclkrst &= ~PHYCLKRST_COMMONONN;

	/* shared reference clock for HS & SS */
	phyclkrst &= ~PHYCLKRST_FSEL_MASK;
	switch (refclkfreq) {
	case PHYCLKRST_FSEL_50M:
		phyclkrst |= PHYCLKRST_FSEL(0x7);
		break;
	case PHYCLKRST_FSEL_24M:
		phyclkrst |= PHYCLKRST_FSEL(0x2);
		hostplltune = readl(regs_base + SAMSUNG_PHY_HOSTPLLTUNE);
		hostplltune |= HOSTPLLTUNE_PLLBTUNE;
		writel(hostplltune, regs_base + SAMSUNG_PHY_HOSTPLLTUNE);
		break;
	default:
		break;
	}
	writel(phyclkrst, regs_base + SAMSUNG_PHYCLKRST);

	/* reset both PHY and Link of Host*/
	stdphyctrl |= STDPHYCTRL_SWRST_PHY;
	stdphyctrl |= STDPHYCTRL_SWRST_ALL;
	writel(stdphyctrl, regs_base + SAMSUNG_PHY_STDPHYCTRL);
	switch (phy_type) {
	case USB_PHY_TYPE_DEVICE:
		otglinkctrl = readl(regs_base + SAMSUNG_LINK_OTGLINKCTL);
		otglinkctrl |= OTGLINKCTRL_SW_RESET_OTG_LINK;
		otglinkctrl |= OTGLINKCTRL_OTG_LINK_PRST;
		writel(otglinkctrl, regs_base + SAMSUNG_LINK_OTGLINKCTL);
		break;
	case USB_PHY_TYPE_HOST:
		hostlinkctrl = readl(regs_base + SAMSUNG_LINK_HOSTLINKCTL);
		hostlinkctrl |= HOSTLINKCTL_LINKSWRST;
		hostlinkctrl |= HOSTLINKCTL_SW_RESET_PORT0;
		hostlinkctrl |= HOSTLINKCTL_SW_RESET_PORT1;
		hostlinkctrl |= HOSTLINKCTL_SW_RESET_PORT2;
		writel(hostlinkctrl, regs_base + SAMSUNG_LINK_HOSTLINKCTL);
		break;
	}

	udelay(10);

	stdphyctrl &= ~STDPHYCTRL_SWRST_ALL;
	stdphyctrl &= ~STDPHYCTRL_SWRST_PHY;
	writel(stdphyctrl, regs_base + SAMSUNG_PHY_STDPHYCTRL);

	switch (phy_type) {
	case USB_PHY_TYPE_DEVICE:
		otglinkctrl &= ~OTGLINKCTRL_SW_RESET_OTG_LINK;
		otglinkctrl &= ~OTGLINKCTRL_OTG_LINK_PRST;
		writel(otglinkctrl, regs_base + SAMSUNG_LINK_OTGLINKCTL);
		break;
	case USB_PHY_TYPE_HOST:
		hostlinkctrl &= ~HOSTLINKCTL_LINKSWRST;
		hostlinkctrl &= ~HOSTLINKCTL_SW_RESET_PORT0;
		hostlinkctrl &= ~HOSTLINKCTL_SW_RESET_PORT1;
		hostlinkctrl &= ~HOSTLINKCTL_SW_RESET_PORT2;
		writel(hostlinkctrl, regs_base + SAMSUNG_LINK_HOSTLINKCTL);
		break;
	}
	udelay(50);
}