static void mx6q_setup_weimcs(void) { unsigned int reg; void __iomem *nor_reg = MX6_IO_ADDRESS(WEIM_BASE_ADDR); void __iomem *ccm_reg = MX6_IO_ADDRESS(CCM_BASE_ADDR); /*CCM_BASE_ADDR + CLKCTL_CCGR6*/ reg = readl(ccm_reg + 0x80); reg |= 0x00000C00; writel(reg, ccm_reg + 0x80); __raw_writel(0x00620081, nor_reg); __raw_writel(0x1C022000, nor_reg + 0x00000008); __raw_writel(0x0804a240, nor_reg + 0x00000010); }
static void __init imx6q_sabreauto_init_usb(void) { int ret = 0; imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR); ret = gpio_request(SABREAUTO_USB_OTG_OC, "otg-oc"); if (ret) { printk(KERN_ERR"failed to get GPIO SABREAUTO_USB_OTG_OC:" " %d\n", ret); return; } gpio_direction_input(SABREAUTO_USB_OTG_OC); ret = gpio_request(SABREAUTO_USB_HOST1_OC, "usbh1-oc"); if (ret) { printk(KERN_ERR"failed to get SABREAUTO_USB_HOST1_OC:" " %d\n", ret); return; } gpio_direction_input(SABREAUTO_USB_HOST1_OC); mxc_iomux_set_gpr_register(1, 13, 1, 0); mx6_set_otghost_vbus_func(imx6q_sabreauto_usbotg_vbus); mx6_usb_dr_init(); mx6_set_host1_vbus_func(imx6q_sabreauto_usbhost1_vbus); #ifdef CONFIG_USB_EHCI_ARC_HSIC mx6_usb_h2_init(); mx6_usb_h3_init(); #endif }
static int mx6_get_srev(void) { void __iomem *anatop = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); u32 rev; if (cpu_is_mx6sl()) rev = __raw_readl(anatop + MX6SL_USB_ANALOG_DIGPROG); else rev = __raw_readl(anatop + MX6_USB_ANALOG_DIGPROG); rev &= 0xff; if (rev == 0) return IMX_CHIP_REVISION_1_0; else if (rev == 1) return IMX_CHIP_REVISION_1_1; else if (rev == 2) return IMX_CHIP_REVISION_1_2; else if (rev == 3) return IMX_CHIP_REVISION_1_3; else if (rev == 4) return IMX_CHIP_REVISION_1_4; else if (rev == 5) return IMX_CHIP_REVISION_1_5; return IMX_CHIP_REVISION_UNKNOWN; }
void __init mx6_usb_h2_init(void) { struct platform_device *pdev, *pdev_wakeup; static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); usbh2_config.wakeup_pdata = &usbh2_wakeup_config; hsic_strobe_start_pad = cpu_is_mx6q() ? MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE_START : (cpu_is_mx6dl() ? MX6DL_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE_START : (cpu_is_mx6sl() ? MX6SL_PAD_HSIC_STROBE__USB_H_STROBE_START : 0)); if (cpu_is_mx6sl()) pdev = imx6sl_add_fsl_ehci_hs(2, &usbh2_config); else pdev = imx6q_add_fsl_ehci_hs(2, &usbh2_config); usbh2_wakeup_config.usb_pdata[0] = pdev->dev.platform_data; if (cpu_is_mx6sl()) pdev_wakeup = imx6sl_add_fsl_usb2_hs_wakeup(2, &usbh2_wakeup_config); else pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(2, &usbh2_wakeup_config); platform_device_add(pdev); ((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata = pdev_wakeup->dev.platform_data; /* Some phy and power's special controls for host2 * 1. Its 480M is from OTG's 480M * 2. EN_USB_CLKS should always be opened */ __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS, anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET); /* must change the clkgate delay to 2 or 3 to avoid * 24M OSCI clock not stable issue */ __raw_writel(BF_ANADIG_ANA_MISC0_CLKGATE_DELAY(3), anatop_base_addr + HW_ANADIG_ANA_MISC0); }
static void __init imx6q_hdmidongle_init_usb(void) { int ret = 0; imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR); /* disable external charger detect, * or it will affect signal quality at dp . */ ret = gpio_request(HDMIDONGLE_USB_OTG_PWR, "usb-pwr"); if (ret) { pr_err("failed to get GPIO HDMIDONGLE_USB_OTG_PWR: %d\n", ret); return; } gpio_direction_output(HDMIDONGLE_USB_OTG_PWR, 0); /* keep USB host1 VBUS always on */ if (board_is_mx6_reva()) { ret = gpio_request(HDMIDONGLE_USB_H1_PWR, "usb-h1-pwr"); if (ret) { pr_err("failed to get GPIO HDMIDONGLE_USB_H1_PWR: %d\n", ret); return; } gpio_direction_output(HDMIDONGLE_USB_H1_PWR, 1); } mxc_iomux_set_gpr_register(1, 13, 1, 1); mx6_set_otghost_vbus_func(imx6q_hdmidongle_usbotg_vbus); }
static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable) { void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR); pr_debug("host1, %s, enable is %d\n", __func__, enable); if (enable) { __raw_writel(BM_USBPHY_CTRL_ENIDCHG_WKUP | BM_USBPHY_CTRL_ENVBUSCHG_WKUP | BM_USBPHY_CTRL_ENDPDMCHG_WKUP | BM_USBPHY_CTRL_ENAUTOSET_USBCLKS | BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD | BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE | BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE | BM_USBPHY_CTRL_ENAUTO_PWRON_PLL , phy_reg + HW_USBPHY_CTRL_SET); USB_H1_CTRL |= (UCTRL_OWIE); } else { __raw_writel(BM_USBPHY_CTRL_ENIDCHG_WKUP | BM_USBPHY_CTRL_ENVBUSCHG_WKUP | BM_USBPHY_CTRL_ENDPDMCHG_WKUP | BM_USBPHY_CTRL_ENAUTOSET_USBCLKS | BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD | BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE | BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE | BM_USBPHY_CTRL_ENAUTO_PWRON_PLL , phy_reg + HW_USBPHY_CTRL_CLR); USB_H1_CTRL &= ~(UCTRL_OWIE); /* The interrupt must be disabled for at least 3 * cycles of the standby clock(32k Hz) , that is 0.094 ms*/ udelay(100); } }
static void __init mx6_arm2_init_usb(void) { int ret = 0; imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR); /* disable external charger detect, * or it will affect signal quality at dp. */ ret = gpio_request(MX6_BRD_USBOTG1_PWR, "usbotg-pwr"); if (ret) { pr_err("failed to get GPIO MX6_BRD_USBOTG1_PWR:%d\n", ret); return; } gpio_direction_output(MX6_BRD_USBOTG1_PWR, 0); ret = gpio_request(MX6_BRD_USBOTG2_PWR, "usbh1-pwr"); if (ret) { pr_err("failed to get GPIO MX6_BRD_USBOTG2_PWR:%d\n", ret); return; } gpio_direction_output(MX6_BRD_USBOTG2_PWR, 1); mx6_set_otghost_vbus_func(imx6_arm2_usbotg_vbus); #ifdef CONFIG_USB_EHCI_ARC_HSIC mxc_iomux_set_specialbits_register(MX6SL_PAD_HSIC_DAT, PAD_CTL_DDR_SEL_DDR3, PAD_CTL_DDR_SEL_MASK); mxc_iomux_set_specialbits_register(MX6SL_PAD_HSIC_STROBE, PAD_CTL_DDR_SEL_DDR3, PAD_CTL_DDR_SEL_MASK); mx6_usb_h2_init(); #endif }
static void __init imx6q_seco_q7_init_usb(void) { int ret = 0; imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR); /* disable external charger detect, * or it will affect signal quality at dp . */ ret = gpio_request(MX6_SECO_A62_USB_OTG_PWR, "usb-pwr"); if (ret) { pr_err("failed to get GPIO MX6_SECO_A62_USB_OTG_PWR: %d\n", ret); return; } gpio_direction_output(MX6_SECO_A62_USB_OTG_PWR, 0); mxc_iomux_set_gpr_register(1, 13, 1, 0); /* * Setting pad control for OTG ID pin UP because the OTG port * is used only as client */ if (cpu_is_mx6q()) mxc_iomux_v3_setup_pad(mx6qd_seco_a62_otg_id_up_pads); else if (cpu_is_mx6dl()) mxc_iomux_v3_setup_pad(mx6sdl_seco_a62_otg_id_up_pads); mx6_set_otghost_vbus_func(imx6q_seco_q7_usbotg_vbus); // mx6_usb_dr_init(); // mx6_usb_h1_init(); }
static void __init mx6_evk_init_usb(void) { int ret = 0; imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR); /* disable external charger detect, * or it will affect signal quality at dp. */ ret = gpio_request(MX6_BRD_USBOTG1_PWR, "usbotg-pwr"); if (ret) { pr_err("failed to get GPIO MX6_BRD_USBOTG1_PWR:%d\n", ret); return; } gpio_direction_output(MX6_BRD_USBOTG1_PWR, 0); ret = gpio_request(MX6_BRD_USBOTG2_PWR, "usbh1-pwr"); if (ret) { pr_err("failed to get GPIO MX6_BRD_USBOTG2_PWR:%d\n", ret); return; } gpio_direction_output(MX6_BRD_USBOTG2_PWR, 1); mx6_set_otghost_vbus_func(imx6_evk_usbotg_vbus); mx6_usb_dr_init(); #ifdef CONFIG_USB_EHCI_ARC_HSIC mx6_usb_h2_init(); #endif }
static int fsl_usb_host_init_ext(struct platform_device *pdev) { static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); int ret; struct clk *usb_clk; /* 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_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); usb_clk = clk_get(NULL, "usboh3_clk"); clk_enable(usb_clk); usb_oh3_clk = usb_clk; ret = fsl_usb_host_init(pdev); if (ret) { printk(KERN_ERR "host1 init fails......\n"); clk_disable(usb_oh3_clk); clk_put(usb_oh3_clk); return ret; } usbh1_internal_phy_clock_gate(true); usb_phy_enable(pdev->dev.platform_data); return 0; }
static int __init post_cpu_init(void) { unsigned int reg; void __iomem *base; iram_init(MX6Q_IRAM_BASE_ADDR, MX6Q_IRAM_SIZE); base = ioremap(AIPS1_ON_BASE_ADDR, PAGE_SIZE); __raw_writel(0x0, base + 0x40); __raw_writel(0x0, base + 0x44); __raw_writel(0x0, base + 0x48); __raw_writel(0x0, base + 0x4C); reg = __raw_readl(base + 0x50) & 0x00FFFFFF; __raw_writel(reg, base + 0x50); iounmap(base); base = ioremap(AIPS2_ON_BASE_ADDR, PAGE_SIZE); __raw_writel(0x0, base + 0x40); __raw_writel(0x0, base + 0x44); __raw_writel(0x0, base + 0x48); __raw_writel(0x0, base + 0x4C); reg = __raw_readl(base + 0x50) & 0x00FFFFFF; __raw_writel(reg, base + 0x50); iounmap(base); if (enable_wait_mode) { /* Allow SCU_CLK to be disabled when all cores are in WFI*/ base = IO_ADDRESS(SCU_BASE_ADDR); reg = __raw_readl(base); reg |= 0x20; __raw_writel(reg, base); } /* Disable SRC warm reset to work aound system reboot issue */ base = IO_ADDRESS(SRC_BASE_ADDR); reg = __raw_readl(base); reg &= ~0x1; __raw_writel(reg, base); gpc_base = MX6_IO_ADDRESS(GPC_BASE_ADDR); ccm_base = MX6_IO_ADDRESS(CCM_BASE_ADDR); num_cpu_idle_lock = 0x0; init_mmdc_settings(); return 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; }
static void usbh1_internal_phy_clock_gate(bool on) { void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR); if (on) { __raw_writel(BM_USBPHY_CTRL_CLKGATE, phy_reg + HW_USBPHY_CTRL_CLR); } else { __raw_writel(BM_USBPHY_CTRL_CLKGATE, phy_reg + HW_USBPHY_CTRL_SET); } }
static void mx6_snvs_poweroff(void) { u32 value; void __iomem *mx6_snvs_base = MX6_IO_ADDRESS(MX6Q_SNVS_BASE_ADDR); value = readl(mx6_snvs_base + SNVS_LPCR); /* set TOP and DP_EN bit */ writel(value | 0x60, mx6_snvs_base + SNVS_LPCR); }
static void usbh1_platform_rh_suspend(struct fsl_usb2_platform_data *pdata) { /*for mx6sl ,we do not need any sw fix*/ if (cpu_is_mx6sl()) return ; __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL_CLR); }
void __init mx6_usb_dr_init(void) { struct platform_device *pdev, *pdev_wakeup; static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); #ifdef CONFIG_USB_OTG /* wake_up_enable is useless, just for usb_register_remote_wakeup execution*/ dr_utmi_config.wake_up_enable = _device_wakeup_enable; dr_utmi_config.operating_mode = FSL_USB2_DR_OTG; dr_utmi_config.wakeup_pdata = &dr_wakeup_config; pdev = imx6q_add_fsl_usb2_otg(&dr_utmi_config); dr_wakeup_config.usb_pdata[0] = pdev->dev.platform_data; #endif #ifdef CONFIG_USB_EHCI_ARC_OTG dr_utmi_config.operating_mode = DR_HOST_MODE; dr_utmi_config.wake_up_enable = _host_wakeup_enable; dr_utmi_config.platform_suspend = _host_platform_suspend; dr_utmi_config.platform_resume = _host_platform_resume; dr_utmi_config.phy_lowpower_suspend = _host_phy_lowpower_suspend; dr_utmi_config.is_wakeup_event = _is_host_wakeup; dr_utmi_config.wakeup_pdata = &dr_wakeup_config; dr_utmi_config.wakeup_handler = host_wakeup_handler; pdev = imx6q_add_fsl_ehci_otg(&dr_utmi_config); dr_wakeup_config.usb_pdata[1] = pdev->dev.platform_data; #endif #ifdef CONFIG_USB_GADGET_ARC dr_utmi_config.operating_mode = DR_UDC_MODE; dr_utmi_config.wake_up_enable = _device_wakeup_enable; dr_utmi_config.platform_suspend = NULL; dr_utmi_config.platform_resume = NULL; dr_utmi_config.phy_lowpower_suspend = _device_phy_lowpower_suspend; dr_utmi_config.is_wakeup_event = _is_device_wakeup; dr_utmi_config.wakeup_pdata = &dr_wakeup_config; dr_utmi_config.wakeup_handler = device_wakeup_handler; pdev = imx6q_add_fsl_usb2_udc(&dr_utmi_config); dr_wakeup_config.usb_pdata[2] = pdev->dev.platform_data; #endif /* register wakeup device */ pdev_wakeup = imx6q_add_fsl_usb2_otg_wakeup(&dr_wakeup_config); if (pdev != NULL) ((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata = (struct fsl_usb2_wakeup_platform_data *)(pdev_wakeup->dev.platform_data); /* Some phy and power's special controls for otg * 1. The external charger detector needs to be disabled * or the signal at DP will be poor * 2. The EN_USB_CLKS is always enabled. * The PLL's power is controlled by usb and others who * use pll3 too. */ __raw_writel(BM_ANADIG_USB1_CHRG_DETECT_EN_B \ | BM_ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B, \ anatop_base_addr + HW_ANADIG_USB1_CHRG_DETECT); __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS, anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET); }
static void usbh1_wakeup_event_clear(void) { void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR); u32 wakeup_irq_bits; wakeup_irq_bits = BM_USBPHY_CTRL_RESUME_IRQ | BM_USBPHY_CTRL_WAKEUP_IRQ; if (__raw_readl(phy_reg + HW_USBPHY_CTRL) && wakeup_irq_bits) { /* clear the wakeup interrupt status */ __raw_writel(wakeup_irq_bits, phy_reg + HW_USBPHY_CTRL_CLR); } }
static void __init imx6q_seco_UDOO_init_usb(void) { imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR); /* disable external charger detect, * or it will affect signal quality at dp . */ mxc_iomux_set_gpr_register(1, 13, 1, 1); mx6_set_otghost_vbus_func(imx6q_seco_UDOO_usbotg_vbus); // mx6_usb_dr_init(); // mx6_usb_h1_init(); }
static void _dr_discharge_line(bool enable) { void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR); if (enable) { __raw_writel(BF_USBPHY_DEBUG_ENHSTPULLDOWN(0x3), phy_reg + HW_USBPHY_DEBUG_SET); __raw_writel(BF_USBPHY_DEBUG_HSTPULLDOWN(0x3), phy_reg + HW_USBPHY_DEBUG_SET); } else { __raw_writel(BF_USBPHY_DEBUG_ENHSTPULLDOWN(0x3), phy_reg + HW_USBPHY_DEBUG_CLR); __raw_writel(BF_USBPHY_DEBUG_HSTPULLDOWN(0x3), phy_reg + HW_USBPHY_DEBUG_CLR); } }
static void fsl_usb_host_uninit_ext(struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); fsl_usb_host_uninit(pdata); clk_disable(usb_oh3_clk); clk_put(usb_oh3_clk); usb_stop_mode_lock(); if (usb_stop_mode_refcount(false) == 0) __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG, anatop_base_addr + HW_ANADIG_ANA_MISC0_CLR); usb_stop_mode_unlock(); }
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; }
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; }
static void _host_platform_resume(struct fsl_usb2_platform_data *pdata) { void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR); u32 tmp; tmp = (BM_USBPHY_PWD_TXPWDFS | BM_USBPHY_PWD_TXPWDIBIAS | BM_USBPHY_PWD_TXPWDV2I | BM_USBPHY_PWD_RXPWDENV | BM_USBPHY_PWD_RXPWD1PT1 | BM_USBPHY_PWD_RXPWDDIFF | BM_USBPHY_PWD_RXPWDRX); __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_CLR); }
/* enable/disable high-speed disconnect detector of phy ctrl */ void fsl_platform_set_usb_phy_dis(struct fsl_usb2_platform_data *pdata, bool enable) { u32 usb_phy_ctrl_dcdt = 0; /* for HSIC, we do not need to enable disconnect detection */ if (pdata->phy_mode == FSL_USB2_PHY_HSIC) return; usb_phy_ctrl_dcdt = __raw_readl( MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL) & BM_USBPHY_CTRL_ENHOSTDISCONDETECT; if (enable) { if (usb_phy_ctrl_dcdt == 0) __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL_SET); } else { if (usb_phy_ctrl_dcdt == BM_USBPHY_CTRL_ENHOSTDISCONDETECT) __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL_CLR); } }
static void __init imx6_init_usb(void) { imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR); /* disable external charger detect, * or it will affect signal quality at dp . */ mxc_iomux_set_gpr_register(1, 13, 1, 1); INIT_DELAYED_WORK(&usb_modem_power_work, usb_modem_power_handler); mx6_set_otghost_vbus_func(imx6_usbotg_vbus); gpio_direction_output(GP_MODEM_RESET, 0); /* modem reset low */ mdelay(50); gpio_direction_input(GP_MODEM_RESET); /* modem reset high */ }
static void __exit mx6_usb_h1_exit(void) { static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); platform_device_unregister(pdev); platform_device_unregister(pdev_wakeup); __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); return ; }
static void _phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable) { u32 tmp; void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR); pr_debug("host1, %s, enable is %d\n", __func__, enable); if (enable) { UH1_PORTSC1 |= PORTSC_PHCD; pr_debug("%s, Poweroff UTMI \n", __func__); tmp = (BM_USBPHY_PWD_TXPWDFS | BM_USBPHY_PWD_TXPWDIBIAS | BM_USBPHY_PWD_TXPWDV2I | BM_USBPHY_PWD_RXPWDENV | BM_USBPHY_PWD_RXPWD1PT1 | BM_USBPHY_PWD_RXPWDDIFF | BM_USBPHY_PWD_RXPWDRX); __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_SET); usbh1_internal_phy_clock_gate(false); } else { if (UH1_PORTSC1 & PORTSC_PHCD) UH1_PORTSC1 &= ~PORTSC_PHCD; /* Wait PHY clock stable */ mdelay(1); usbh1_internal_phy_clock_gate(true); udelay(2); tmp = (BM_USBPHY_PWD_TXPWDFS | BM_USBPHY_PWD_TXPWDIBIAS | BM_USBPHY_PWD_TXPWDV2I | BM_USBPHY_PWD_RXPWDENV | BM_USBPHY_PWD_RXPWD1PT1 | BM_USBPHY_PWD_RXPWDDIFF | BM_USBPHY_PWD_RXPWDRX); __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_CLR); /* * The PHY works at 32Khz clock when it is at low power mode, * it needs 10 clocks from 32Khz to normal work state, so * 500us is the safe value for PHY enters stable status * according to IC engineer. */ udelay(500); } }
static void fsl_usb_host_uninit_ext(struct platform_device *pdev) { static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; fsl_usb_host_uninit(pdata); clk_put(usb_oh3_clk); __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); }
void __init mx6_usb_h2_init(void) { struct platform_device *pdev, *pdev_wakeup; static void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR); usbh2_config.wakeup_pdata = &usbh2_wakeup_config; pdev = imx6q_add_fsl_ehci_hs(2, &usbh2_config); usbh2_wakeup_config.usb_pdata[0] = pdev->dev.platform_data; pdev_wakeup = imx6q_add_fsl_usb2_hs_wakeup(2, &usbh2_wakeup_config); ((struct fsl_usb2_platform_data *)(pdev->dev.platform_data))->wakeup_pdata = pdev_wakeup->dev.platform_data; /* Some phy and power's special controls for host2 * 1. Its 480M is from OTG's 480M * 2. EN_USB_CLKS should always be opened */ __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS, anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET); }
static __init void wand_init_usb(void) { wand_mux_pads_init_usb(); gpio_request(WAND_USB_OTG_OC, "otg oc"); gpio_direction_input(WAND_USB_OTG_OC); gpio_request(WAND_USB_OTG_PWR, "otg pwr"); gpio_direction_output(WAND_USB_OTG_PWR, 0); imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR); mxc_iomux_set_gpr_register(1, 13, 1, 1); mx6_set_otghost_vbus_func(wand_usbotg_vbus); gpio_request(WAND_USB_H1_OC, "usbh1 oc"); gpio_direction_input(WAND_USB_H1_OC); }