static int exynos5_check_usb_op(void)
{
	u32 hostphy_ctrl0, otgphy_sys;
	u32 op = 1;
	unsigned long flags;
	int ret;

	ret = clk_enable(phy_clk);
	if (ret)
		return 0;

	local_irq_save(flags);
	/* Check USB 3.0 DRD power */
	if (exynos5_usb_phy30_is_on()) {
		op = 1;
		goto done;
	}
	/*If USB Device is power on,  */
	if (exynos_usb_device_phy_is_on()) {
		op = 1;
		goto done;
	} else if (!exynos5_usb_host_phy20_is_on()) {
		op = 0;
		goto done;
	}

	hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0);

	if (hostphy_ctrl0 & HOST_CTRL0_FORCESUSPEND) {
		/* unset to normal of Host */
		hostphy_ctrl0 |= (HOST_CTRL0_SIDDQ);
		writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);

		/* unset to normal of Device */
		otgphy_sys = readl(EXYNOS5_PHY_OTG_SYS);
		otgphy_sys |= OTG_SYS_SIDDQ_UOTG;
		writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);

		exynos_usb_phy_control(USB_PHY1,
			PHY_DISABLE);

		op = 0;
		usb_phy_control.lpa_entered = 1;
	}
done:
	local_irq_restore(flags);
	clk_disable(phy_clk);

	return op;
}
Example #2
0
static int exynos5_usb_dev_phy20_init(struct platform_device *pdev)
{
	struct clk *otg_clk;
	struct clk *host_clk;
	int err;

	exynos4_usb_phy_control(USB_PHY1, PHY_ENABLE);

	host_clk = clk_get(&pdev->dev, "usbhost");
	if (IS_ERR(host_clk)) {
		dev_err(&pdev->dev, "Failed to get otg clock\n");
		return PTR_ERR(host_clk);
	}

	err = clk_enable(host_clk);
	if (err) {
		clk_put(host_clk);
		return err;
	}

	if (!exynos5_usb_host_phy20_is_on()) {
		exynos5_usb_phy20_init(pdev);
	}
	clk_disable(host_clk);
	clk_put(host_clk);

	otg_clk = clk_get(&pdev->dev, "usbotg");
	if (IS_ERR(otg_clk)) {
		dev_err(&pdev->dev, "Failed to get otg clock\n");
		return PTR_ERR(otg_clk);
	}

	err = clk_enable(otg_clk);
	if (err) {
		clk_put(otg_clk);
		return err;
	}

	exynos_usb_mux_change(pdev, 0);

	clk_put(otg_clk);
	return 0;
}
static int exynos5_usb_phy20_init(struct platform_device *pdev)
{
	u32 refclk_freq;
	u32 hostphy_ctrl0, otgphy_sys, hsic_ctrl, ehcictrl, ohcictrl;

	atomic_inc(&host_usage);

	if (exynos5_usb_host_phy20_is_on()) {
		dev_err(&pdev->dev, "Already power on PHY\n");
		return 0;
	}

	exynos_usb_mux_change(pdev, 1);

	exynos_usb_phy_control(USB_PHY1, PHY_ENABLE);

	/* Host and Device should be set at the same time */
	hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0);
	hostphy_ctrl0 &= ~(HOST_CTRL0_FSEL_MASK);
	otgphy_sys = readl(EXYNOS5_PHY_OTG_SYS);
	otgphy_sys &= ~(OTG_SYS_CTRL0_FSEL_MASK);

	/* 2.0 phy reference clock configuration */
	refclk_freq = exynos_usb_phy_set_clock(pdev);
	hostphy_ctrl0 |= (refclk_freq << HOST_CTRL0_CLKSEL_SHIFT);
	otgphy_sys |= (refclk_freq << OTG_SYS_CLKSEL_SHIFT);

	/* COMMON Block configuration during suspend */
	hostphy_ctrl0 |= HOST_CTRL0_COMMONON_N;
	otgphy_sys &= ~(OTG_SYS_COMMON_ON);

	/* otg phy reset */
	otgphy_sys &= ~(OTG_SYS_FORCE_SUSPEND | OTG_SYS_SIDDQ_UOTG | OTG_SYS_FORCE_SLEEP);
	otgphy_sys &= ~(OTG_SYS_REF_CLK_SEL_MASK);
	otgphy_sys |= (OTG_SYS_REF_CLK_SEL(0x2) | OTG_SYS_OTGDISABLE);
	otgphy_sys |= (OTG_SYS_PHY0_SW_RST | OTG_SYS_LINK_SW_RST_UOTG | OTG_SYS_PHYLINK_SW_RESET);
	writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);
	udelay(10);
	otgphy_sys &= ~(OTG_SYS_PHY0_SW_RST | OTG_SYS_LINK_SW_RST_UOTG | OTG_SYS_PHYLINK_SW_RESET);
	writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);

	/* host phy reset */
	hostphy_ctrl0 &= ~(HOST_CTRL0_PHYSWRST | HOST_CTRL0_PHYSWRSTALL | HOST_CTRL0_SIDDQ);
	hostphy_ctrl0 &= ~(HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP);
	hostphy_ctrl0 |= (HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
	writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
	udelay(10);
	hostphy_ctrl0 &= ~(HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
	writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);

	/* HSIC phy reset */
	hsic_ctrl = (HSIC_CTRL_REFCLKDIV(0x24) | HSIC_CTRL_REFCLKSEL(0x2) |
		HSIC_CTRL_PHYSWRST);
	writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
	writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
	udelay(10);
	hsic_ctrl &= ~(HSIC_CTRL_PHYSWRST);
	writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
	writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);

	udelay(80);
	/* enable EHCI DMA burst  */
	ehcictrl = readl(EXYNOS5_PHY_HOST_EHCICTRL);
	ehcictrl |= (EHCICTRL_ENAINCRXALIGN | EHCICTRL_ENAINCR4 |
			EHCICTRL_ENAINCR8 | EHCICTRL_ENAINCR16);
	writel(ehcictrl, EXYNOS5_PHY_HOST_EHCICTRL);
	/* set ohci_suspend_on_n */
	ohcictrl = readl(EXYNOS5_PHY_HOST_OHCICTRL);
	ohcictrl |= OHCICTRL_SUSPLGCY;
	writel(ohcictrl, EXYNOS5_PHY_HOST_OHCICTRL);
	return 0;
}
static int exynos5_usb_phy_host_resume(struct platform_device *pdev)
{
	u32 hostphy_ctrl0, otgphy_sys, hsic_ctrl;
	int err;

	if (exynos5_usb_host_phy20_is_on()) {
		/* set to suspend HSIC 0 and 1 and standard of PHY1 */
		hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0);
		hostphy_ctrl0 &= ~(HOST_CTRL0_FORCESUSPEND);
		writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);

		/* set common_on_n of PHY1 for power consumption */
		hsic_ctrl = readl(EXYNOS5_PHY_HSIC_CTRL1);
		hsic_ctrl &= ~(HSIC_CTRL_FORCESUSPEND);
		writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
		writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
		if (usb_phy_control.lpa_entered) {
			usb_phy_control.lpa_entered = 0;
			err = 1;
		} else
			err = 0;
	} else {
		exynos_usb_phy_control(USB_PHY1, PHY_ENABLE);

		/* otg phy reset */
		otgphy_sys = readl(EXYNOS5_PHY_OTG_SYS);
		otgphy_sys &= ~(OTG_SYS_SIDDQ_UOTG);
		otgphy_sys |= (OTG_SYS_PHY0_SW_RST |
				OTG_SYS_LINK_SW_RST_UOTG |
				OTG_SYS_PHYLINK_SW_RESET);
		writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);
		udelay(10);
		otgphy_sys &= ~(OTG_SYS_PHY0_SW_RST |
				OTG_SYS_LINK_SW_RST_UOTG |
				OTG_SYS_PHYLINK_SW_RESET);
		writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);

		/* reset all ports of both PHY and Link */
		hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0);
		hostphy_ctrl0 &= ~(HOST_CTRL0_SIDDQ | HOST_CTRL0_FORCESUSPEND);
		hostphy_ctrl0 |= (HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
		writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
		udelay(10);
		hostphy_ctrl0 &= ~(HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
		writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);

		/* HSIC phy reset */
		hsic_ctrl = readl(EXYNOS5_PHY_HSIC_CTRL1);
		hsic_ctrl &= ~(HSIC_CTRL_SIDDQ | HSIC_CTRL_FORCESUSPEND);
		hsic_ctrl |= (HSIC_CTRL_PHYSWRST | HSIC_CTRL_UTMISWRST);
		writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
		writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
		udelay(10);
		hsic_ctrl &= ~(HSIC_CTRL_PHYSWRST | HSIC_CTRL_UTMISWRST);
		writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
		writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);

		usb_phy_control.lpa_entered = 0;
		err = 1;
	}
	udelay(80);

	return err;
}
Example #5
0
static int exynos5_usb_phy20_init(struct platform_device *pdev)
{
	struct clk *ext_xtal;
	u32 refclk_freq;
	u32 hostphy_ctrl0;
	u32 otgphy_sys;
	u32 hsic_ctrl;
	u32 ehcictrl;

	exynos4_usb_phy_control(USB_PHY1, PHY_ENABLE);

	if (exynos5_usb_host_phy20_is_on()) {
		dev_err(&pdev->dev, "Already power on PHY\n");
		return 0;
	}

	exynos_usb_mux_change(pdev, 1);

	/* Host and Device should be set at the same time */
	hostphy_ctrl0 = readl(EXYNOS5_PHY_HOST_CTRL0);
	hostphy_ctrl0 &= ~(HOST_CTRL0_FSEL_MASK);
	otgphy_sys = readl(EXYNOS5_PHY_OTG_SYS);
	otgphy_sys &= ~(OTG_SYS_CTRL0_FSEL_MASK);

	/* 2.0 phy reference clock configuration */
	ext_xtal = clk_get(&pdev->dev, "ext_xtal");
	switch (clk_get_rate(ext_xtal)) {
	case 96 * 100000:
		refclk_freq = EXYNOS5_CLKSEL_9600K;
		break;
	case 10 * MHZ:
		refclk_freq = EXYNOS5_CLKSEL_10M;
		break;
	case 12 * MHZ:
		refclk_freq = EXYNOS5_CLKSEL_12M;
		break;
	case 192 * 100000:
		refclk_freq = EXYNOS5_CLKSEL_19200K;
		break;
	case 20 * MHZ:
		refclk_freq = EXYNOS5_CLKSEL_20M;
		break;
	case 24 * MHZ:
		refclk_freq = EXYNOS5_CLKSEL_24M;
		break;
	default:
	case 50 * MHZ:
		/* default reference clock */
		refclk_freq = EXYNOS5_CLKSEL_50M;
		break;
	}
	hostphy_ctrl0 |= (refclk_freq << HOST_CTRL0_CLKSEL_SHIFT);
	otgphy_sys |= (refclk_freq << OTG_SYS_CLKSEL_SHIFT);

	/* COMMON Block configuration during suspend */
	hostphy_ctrl0 &= ~(HOST_CTRL0_COMMONON_N);
	otgphy_sys |= (OTG_SYS_COMMON_ON);

	/* otg phy reset */
	otgphy_sys &= ~(OTG_SYS_FORCE_SUSPEND | OTG_SYS_SIDDQ_UOTG | OTG_SYS_FORCE_SLEEP);
	otgphy_sys &= ~(OTG_SYS_REF_CLK_SEL_MASK);
	otgphy_sys |= (OTG_SYS_REF_CLK_SEL(0x2) | OTG_SYS_OTGDISABLE);
	otgphy_sys |= (OTG_SYS_PHY0_SW_RST | OTG_SYS_LINK_SW_RST_UOTG | OTG_SYS_PHYLINK_SW_RESET);
	writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);
	udelay(10);
	otgphy_sys &= ~(OTG_SYS_PHY0_SW_RST | OTG_SYS_LINK_SW_RST_UOTG | OTG_SYS_PHYLINK_SW_RESET);
	writel(otgphy_sys, EXYNOS5_PHY_OTG_SYS);

	/* host phy reset */
	hostphy_ctrl0 &= ~(HOST_CTRL0_PHYSWRST | HOST_CTRL0_PHYSWRSTALL | HOST_CTRL0_SIDDQ);
	hostphy_ctrl0 &= ~(HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP);
	hostphy_ctrl0 |= (HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
	writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);
	udelay(10);
	hostphy_ctrl0 &= ~(HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
	writel(hostphy_ctrl0, EXYNOS5_PHY_HOST_CTRL0);

	/* HSIC phy reset */
	hsic_ctrl = (HSIC_CTRL_REFCLKDIV(0x24) | HSIC_CTRL_REFCLKSEL(0x2) |
		HSIC_CTRL_PHYSWRST);
	writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
	writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);
	udelay(10);
	hsic_ctrl &= ~(HSIC_CTRL_PHYSWRST);
	writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL1);
	writel(hsic_ctrl, EXYNOS5_PHY_HSIC_CTRL2);

	udelay(80);

	ehcictrl = readl(EXYNOS5_PHY_HOST_EHCICTRL);
	ehcictrl |= (EHCICTRL_ENAINCRXALIGN | EHCICTRL_ENAINCR4 |
			EHCICTRL_ENAINCR8 | EHCICTRL_ENAINCR16);
	writel(ehcictrl, EXYNOS5_PHY_HOST_EHCICTRL);

	return 0;
}