예제 #1
0
static int  __init mx6_usb_h1_init(void)
{
    static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
    struct imx_fsl_usb2_wakeup_data imx6q_fsl_hs_wakeup_data[] = {
        imx_fsl_usb2_wakeup_data_entry_single(MX6Q, 1, HS1)
    };
    struct imx_fsl_usb2_wakeup_data  imx6sl_fsl_hs_wakeup_data[] = {
        imx_fsl_usb2_wakeup_data_entry_single(MX6SL, 1, HS1)
    };
    struct imx_mxc_ehci_data imx6q_mxc_ehci_hs_data[] = {
        imx_mxc_ehci_data_entry_single(MX6Q, 1, HS1)
    };
    struct imx_mxc_ehci_data imx6sl_mxc_ehci_hs_data[] = {
        imx_mxc_ehci_data_entry_single(MX6SL, 1, HS1)
    };

    mx6_get_host1_vbus_func(&mx6_set_usb_host1_vbus);
    if (mx6_set_usb_host1_vbus)
        mx6_set_usb_host1_vbus(true);

    /* Some phy and power's special controls for host1
     * 1. The external charger detector needs to be disabled
     * or the signal at DP will be poor
     * 2. The PLL's power and output to usb for host 1
     * is totally controlled by IC, so the Software only needs
     * to enable them at initializtion.
     */
    __raw_writel(BM_ANADIG_USB2_CHRG_DETECT_EN_B  \
                 | BM_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B, \
                 anatop_base_addr + HW_ANADIG_USB2_CHRG_DETECT);
    __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_BYPASS,
                 anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_CLR);
    __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_ENABLE  \
                 | BM_ANADIG_USB2_PLL_480_CTRL_POWER \
                 | BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS, \
                 anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_SET);

    usbh1_config.wakeup_pdata = &usbh1_wakeup_config;
    if (usb_icbug_swfix_need()) {
        usbh1_config.platform_rh_suspend = usbh1_platform_rh_suspend_swfix;
        usbh1_config.platform_rh_resume  = usbh1_platform_rh_resume_swfix;
    } else {
        usbh1_config.platform_rh_suspend = usbh1_platform_rh_suspend;
        usbh1_config.platform_rh_resume  = usbh1_platform_rh_resume;
    }
    if (cpu_is_mx6sl())
        pdev = imx6sl_add_fsl_ehci_hs(1, &usbh1_config);
    else
        pdev = imx6q_add_fsl_ehci_hs(1, &usbh1_config);
    usbh1_wakeup_config.usb_pdata[0] = pdev->dev.platform_data;
    if (cpu_is_mx6sl())
        pdev_wakeup = imx6sl_add_fsl_usb2_hs_wakeup(1, &usbh1_wakeup_config);
    else
        pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(1, &usbh1_wakeup_config);
    platform_device_add(pdev);
    ((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata =
        (struct fsl_usb2_wakeup_platform_data *)(pdev_wakeup->dev.platform_data);
    return 0;
}
예제 #2
0
static int  __init mx6_usb_h1_init(void)
{
	static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
	struct imx_fsl_usb2_wakeup_data imx6q_fsl_hs_wakeup_data[] = {
		imx_fsl_usb2_wakeup_data_entry_single(MX6Q, 1, HS1)};
	struct imx_fsl_usb2_wakeup_data  imx6sl_fsl_hs_wakeup_data[] = {
		imx_fsl_usb2_wakeup_data_entry_single(MX6SL, 1, HS1)};
	struct imx_mxc_ehci_data imx6q_mxc_ehci_hs_data[] = {
		imx_mxc_ehci_data_entry_single(MX6Q, 1, HS1)};
	struct imx_mxc_ehci_data imx6sl_mxc_ehci_hs_data[] = {
		imx_mxc_ehci_data_entry_single(MX6SL, 1, HS1)};

	mx6_get_host1_vbus_func(&mx6_set_usb_host1_vbus);
	usbh1_config.platform_driver_vbus = mx6_set_usb_host1_vbus;

	/* The external charger detector needs to be disabled
	 * or the signal at DP will be poor
	 */
	__raw_writel(BM_ANADIG_USB2_CHRG_DETECT_EN_B  \
			| BM_ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B, \
			anatop_base_addr + HW_ANADIG_USB2_CHRG_DETECT);
	/* Turn off PHY PLL until USB host driver is loaded */
	__raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_BYPASS,
			anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_SET);
	__raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_ENABLE  \
			| BM_ANADIG_USB2_PLL_480_CTRL_POWER \
			| BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS, \
			anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_CLR);

	usbh1_config.wakeup_pdata = &usbh1_wakeup_config;
	if (usb_icbug_swfix_need()) {
		usbh1_config.platform_rh_suspend = usbh1_platform_rh_suspend_swfix;
		usbh1_config.platform_rh_resume  = usbh1_platform_rh_resume_swfix;
	} else {
		usbh1_config.platform_rh_suspend = usbh1_platform_rh_suspend;
		usbh1_config.platform_rh_resume  = usbh1_platform_rh_resume;
	}
	if (cpu_is_mx6sl())
		pdev = imx6sl_add_fsl_ehci_hs(1, &usbh1_config);
	else
		pdev = imx6q_add_fsl_ehci_hs(1, &usbh1_config);
	usbh1_wakeup_config.usb_pdata[0] = pdev->dev.platform_data;
	if (cpu_is_mx6sl())
		pdev_wakeup = imx6sl_add_fsl_usb2_hs_wakeup(1, &usbh1_wakeup_config);
	else
		pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(1, &usbh1_wakeup_config);
	platform_device_add(pdev);
	((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata =
		(struct fsl_usb2_wakeup_platform_data *)(pdev_wakeup->dev.platform_data);
	return 0;
}
예제 #3
0
static int usb_phy_enable(struct fsl_usb2_platform_data *pdata)
{
	u32 tmp;
	void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR);
	void __iomem *phy_ctrl;

	/* Stop then Reset */
	UH1_USBCMD &= ~UCMD_RUN_STOP;
	while (UH1_USBCMD & UCMD_RUN_STOP)
		;

	UH1_USBCMD |= UCMD_RESET;
	while ((UH1_USBCMD) & (UCMD_RESET))
		;

	/*
	 * If the controller reset does not put the PHY be out of
	 * low power mode, do it manually.
	 */
	if (UH1_PORTSC1 & PORTSC_PHCD) {
		UH1_PORTSC1 &= ~PORTSC_PHCD;
		mdelay(1);
	}

	/* Reset USBPHY module */
	phy_ctrl = phy_reg + HW_USBPHY_CTRL;
	tmp = __raw_readl(phy_ctrl);
	tmp |= BM_USBPHY_CTRL_SFTRST;
	__raw_writel(tmp, phy_ctrl);
	udelay(10);

	/* Remove CLKGATE and SFTRST */
	tmp = __raw_readl(phy_ctrl);
	tmp &= ~(BM_USBPHY_CTRL_CLKGATE | BM_USBPHY_CTRL_SFTRST);
	__raw_writel(tmp, phy_ctrl);
	udelay(10);

	/* Power up the PHY */
	__raw_writel(0, phy_reg + HW_USBPHY_PWD);
	/* enable FS/LS device */
	tmp = __raw_readl(phy_reg + HW_USBPHY_CTRL);
	tmp |= (BM_USBPHY_CTRL_ENUTMILEVEL2 | BM_USBPHY_CTRL_ENUTMILEVEL3);
	__raw_writel(tmp, phy_reg + HW_USBPHY_CTRL);

	if (!usb_icbug_swfix_need())
		__raw_writel((1 << 17), phy_reg + HW_USBPHY_IP_SET);
	if (cpu_is_mx6sl())
		__raw_writel((1 << 18), phy_reg + HW_USBPHY_IP_SET);
	return 0;
}