static int __init post_cpu_init(void) { unsigned int reg; void __iomem *base; if (cpu_is_mx51() || cpu_is_mx53()) { if (cpu_is_mx51()) base = MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR); else base = MX53_IO_ADDRESS(MX53_AIPS1_BASE_ADDR); __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); if (cpu_is_mx51()) base = MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR); else base = MX53_IO_ADDRESS(MX53_AIPS2_BASE_ADDR); __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); } return 0; }
static int fsl_usb_host_init_ext(struct platform_device *pdev) { iomux_v3_cfg_t usbh1stp_func = MX51_PAD_USBH1_STP__USBH1_STP; int ret; struct clk *usb_clk; /* the usb_ahb_clk will be enabled in usb_otg_init */ usb_ahb_clk = clk_get(NULL, "usb_ahb_clk"); if (cpu_is_mx53()) { usb_clk = clk_get(NULL, "usboh3_clk"); clk_enable(usb_clk); usb_oh3_clk = usb_clk; usb_clk = clk_get(NULL, "usb_phy2_clk"); clk_enable(usb_clk); usb_phy2_clk = usb_clk; } else if (cpu_is_mx50()) { usb_clk = clk_get(NULL, "usb_phy2_clk"); clk_enable(usb_clk); usb_phy2_clk = usb_clk; } else if (cpu_is_mx51()) { usb_clk = clk_get(NULL, "usboh3_clk"); clk_enable(usb_clk); usb_oh3_clk = usb_clk; } ret = fsl_usb_host_init(pdev); if (ret) return ret; if (cpu_is_mx51()) { /* setback USBH1_STP to be function */ #if 0 /* Jasper: Need to do... */ mxc_request_iomux(MX51_PIN_USBH1_STP, IOMUX_CONFIG_ALT0); mxc_iomux_set_pad(MX51_PIN_USBH1_STP, PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS | PAD_CTL_DRV_VOT_LOW); gpio_free(IOMUX_TO_GPIO(MX51_PIN_USBH1_STP)); #endif mxc_iomux_v3_setup_pad(usbh1stp_func); gpio_free(MX5X_USBH1_STP); } /* disable remote wakeup irq */ USBCTRL &= ~UCTRL_H1WIE; return 0; }
void force_freq_change(void) { u32 reg; int rate; u32 flags; #ifndef DVFS_SW_WORKAROUND /* Increase the LP domain voltage first. */ mx37_set_lp_voltage(LP_NORMAL_VOLTAGE); udelay(100); #endif freq_increased = 0; spin_lock_irqsave(&mxc_dvfs_per_lock, flags); // printk("force_freq_change\n"); reg = __raw_readl(MXC_DVFS_PER_PMCR0); reg |= MXC_DVFSPMCR0_UDCS; __raw_writel(reg, MXC_DVFS_PER_PMCR0); if (cpu_is_mx51()) { /*Change the DDR freq to 133Mhz. */ clk_set_rate(ddr_hf_clk, clk_round_rate(ddr_hf_clk, 200000000)); } #ifndef DVFS_SW_WORKAROUND reg = __raw_readl(MXC_GPC_CNTR); reg |= MXC_GPCCNTR_FUPD; __raw_writel(reg, MXC_GPC_CNTR); reg = __raw_readl(MXC_GPC_VCR); reg &= ~(MXC_GPCVCR_VINC_MASK | MXC_GPCVCR_VCNTU_MASK | MXC_GPCVCR_VCNT_MASK); reg |= (1 << MXC_GPCVCR_VINC_OFFSET | 1 << MXC_GPCVCR_VCNTU_OFFSET | 20 << MXC_GPCVCR_VCNT_OFFSET); __raw_writel(reg, MXC_GPC_VCR); reg = __raw_readl(MXC_GPC_CNTR); reg &= ~MXC_GPCCNTR_ADU; reg |= MXC_GPCCNTR_STRT; __raw_writel(reg, MXC_GPC_CNTR); while (__raw_readl(MXC_GPC_CNTR) & 0x4000) { udelay(10); } freq_increased = 1; #else //Set the frequencies manually rate = clk_get_rate(axi_b_clk); clk_set_rate(axi_b_clk, clk_round_rate(axi_b_clk, 130000000)); rate = clk_get_rate(ahb_clk); clk_set_rate(ahb_clk, clk_round_rate(ahb_clk, 130000000)); #endif #ifndef DVFS_SW_WORKAROUND clk_set_parent(main_bus_clk, clk_get(NULL, "pll2")); #endif spin_unlock_irqrestore(&mxc_dvfs_per_lock, flags); }
static inline void *_get_sw_pad(void) { if (cpu_is_mx51()) return IO_ADDRESS(IOMUXC_BASE_ADDR) + PAD_I_START_MX51; else return IO_ADDRESS(IOMUXC_BASE_ADDR) + PAD_I_START_MX53; }
static inline void __iomem *_get_pll_base(struct clk *pll) { if (cpu_is_mx51()) return _mx51_get_pll_base(pll); else return _mx53_get_pll_base(pll); }
int set_low_bus_freq(void) { if (busfreq_suspended) return 0; if (bus_freq_scaling_initialized) { /* can not enter low bus freq, when cpu is in higher freq * or only have one working point */ if ((clk_get_rate(cpu_clk) > cpu_wp_tbl[cpu_wp_nr - 1].cpu_rate) || (cpu_wp_nr == 1)) { return 0; } mutex_lock(&bus_freq_mutex); stop_dvfs_per(); stop_sdram_autogating(); if (cpu_is_mx50()) enter_lpapm_mode_mx50(); else if (cpu_is_mx51()) enter_lpapm_mode_mx51(); else enter_lpapm_mode_mx53(); mutex_unlock(&bus_freq_mutex); } return 0; }
/*! * This function configures input path. * * @param input index of input select register as defined in \b #iomux_input_select_t * @param config the binary value of elements defined in \b #iomux_input_config_t * */ void mxc_iomux_set_input(iomux_input_select_t input, u32 config) { void __iomem *reg; if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) { if (input == MUX_IN_IPU_IPP_DI_0_IND_DISPB_SD_D_SELECT_INPUT) input -= 4; else if (input == MUX_IN_IPU_IPP_DI_1_IND_DISPB_SD_D_SELECT_INPUT) input -= 3; else if (input >= MUX_IN_KPP_IPP_IND_COL_6_SELECT_INPUT) input -= 2; else if (input >= MUX_IN_HSC_MIPI_MIX_PAR_SISG_TRIG_SELECT_INPUT) input -= 5; else if (input >= MUX_IN_HSC_MIPI_MIX_IPP_IND_SENS1_DATA_EN_SELECT_INPUT) input -= 3; else if (input >= MUX_IN_ECSPI2_IPP_IND_SS_B_3_SELECT_INPUT) input -= 2; else if (input >= MUX_IN_CCM_PLL1_BYPASS_CLK_SELECT_INPUT) input -= 1; reg = IOMUXSW_INPUT_CTL + (input << 2) + INPUT_CTL_START_MX51_TO1; } else if (cpu_is_mx51()) { reg = IOMUXSW_INPUT_CTL + (input << 2) + INPUT_CTL_START_MX51; } else reg = IOMUXSW_INPUT_CTL + (input << 2) + INPUT_CTL_START_MX53; BUG_ON(input >= MUX_INPUT_NUM_MUX); __raw_writel(config, reg); }
int fsl_udc_clk_init(struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata; unsigned long freq; int ret; pdata = pdev->dev.platform_data; if (!cpu_is_mx35() && !cpu_is_mx25()) { mxc_ahb_clk = clk_get(&pdev->dev, "usb_ahb"); if (IS_ERR(mxc_ahb_clk)) return PTR_ERR(mxc_ahb_clk); ret = clk_enable(mxc_ahb_clk); if (ret < 0) { dev_err(&pdev->dev, "clk_enable(\"usb_ahb\") failed\n"); goto eenahb; } } /* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */ mxc_usb_clk = clk_get(&pdev->dev, "usb"); if (IS_ERR(mxc_usb_clk)) { dev_err(&pdev->dev, "clk_get(\"usb\") failed\n"); ret = PTR_ERR(mxc_usb_clk); goto egusb; } if (!cpu_is_mx51()) { freq = clk_get_rate(mxc_usb_clk); if (pdata->phy_mode != FSL_USB2_PHY_ULPI && (freq < 59999000 || freq > 60001000)) { dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq); ret = -EINVAL; goto eclkrate; } } ret = clk_enable(mxc_usb_clk); if (ret < 0) { dev_err(&pdev->dev, "clk_enable(\"usb_clk\") failed\n"); goto eenusb; } return 0; eenusb: eclkrate: clk_put(mxc_usb_clk); mxc_usb_clk = NULL; egusb: if (!cpu_is_mx35()) clk_disable(mxc_ahb_clk); eenahb: if (!cpu_is_mx35()) clk_put(mxc_ahb_clk); return ret; }
void __init mx5_usbh1_init(void) { if (cpu_is_mx51()) { usbh1_config.phy_mode = FSL_USB2_PHY_ULPI; usbh1_config.transceiver = "isp1504"; usbh1_config.gpio_usb_active = gpio_usbh1_active; usbh1_config.gpio_usb_inactive = gpio_usbh1_inactive; } mxc_register_device(&mxc_usbh1_device, &usbh1_config); }
/* * Returns: * the silicon revision of the cpu * -EINVAL - not a mx51 */ int mx51_revision(void) { if (!cpu_is_mx51()) return -EINVAL; if (cpu_silicon_rev == -1) query_silicon_parameter(); return cpu_silicon_rev; }
/* * Returns: * the silicon revision of the cpu * -EINVAL - not a mx51 */ int mx51_revision(void) { if (!cpu_is_mx51()) return -EINVAL; if (cpu_silicon_rev == -1) cpu_silicon_rev = get_mx51_srev(); return cpu_silicon_rev; }
/* * Returns: * the silicon revision of the cpu * -EINVAL - not a mx51 */ int mx51_revision(void) { if (!cpu_is_mx51()) return -EINVAL; if (mx5_cpu_rev == -1) mx5_cpu_rev = get_mx51_srev(); return mx5_cpu_rev; }
/* * All versions of the silicon before Rev. 3 have broken NEON implementations. * Dependent on link order - so the assumption is that vfp_init is called * before us. */ static int __init mx51_neon_fixup(void) { if (!cpu_is_mx51()) return 0; if (mx51_revision() < IMX_CHIP_REVISION_3_0 && (elf_hwcap & HWCAP_NEON)) { elf_hwcap &= ~HWCAP_NEON; pr_info("Turning off NEON support, detected broken NEON implementation\n"); } return 0; }
/****************************************************************************** * * CAUTION: NONE * * MODIFICATION HISTORY: * * Date Person Change * 30/07/2003 MW Initial Creation ******************************************************************************/ void sah_Intr_Release(void) { int irq_sah = MX53_INT_SAHARA_H0; if (cpu_is_mx51()) irq_sah = MX51_MXC_INT_SAHARA_H0; /* Release the Interrupt. */ free_irq(irq_sah, NULL); }
static void force_freq_change(void) { u32 reg; int retry = 50; freq_increased = 0; reg = __raw_readl(dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR0); reg |= MXC_DVFSPMCR0_UDCS; __raw_writel(reg, dvfsper_plt_data->membase + MXC_DVFS_PER_PMCR0); if (cpu_is_mx51()) { /*Change the DDR freq to 133Mhz. */ clk_set_rate(ddr_hf_clk, clk_round_rate(ddr_hf_clk, 200000000)); } #ifndef DVFS_SW_WORKAROUND reg = __raw_readl(dvfsper_plt_data->gpc_cntr_reg_addr); reg |= MXC_GPCCNTR_FUPD; __raw_writel(reg, dvfsper_plt_data->gpc_cntr_reg_addr); reg = __raw_readl(dvfsper_plt_data->gpc_vcr_reg_addr); reg &= ~(MXC_GPCVCR_VINC_MASK | MXC_GPCVCR_VCNTU_MASK | MXC_GPCVCR_VCNT_MASK); reg |= (1 << MXC_GPCVCR_VINC_OFFSET | 1 << MXC_GPCVCR_VCNTU_OFFSET | 20 << MXC_GPCVCR_VCNT_OFFSET); __raw_writel(reg, dvfsper_plt_data->gpc_vcr_reg_addr); reg = __raw_readl(dvfsper_plt_data->gpc_cntr_reg_addr); reg &= ~MXC_GPCCNTR_ADU; reg |= MXC_GPCCNTR_STRT; __raw_writel(reg, dvfsper_plt_data->gpc_cntr_reg_addr); while ((__raw_readl( dvfsper_plt_data->gpc_cntr_reg_addr) & 0x4000) && retry > 0) { udelay(30); retry--; } freq_increased = 1; if (retry <= 0) printk(KERN_ERR "Cannot stop DVFS-PER\n"); #else /* Set the frequencies manually */ rate = clk_get_rate(axi_b_clk); clk_set_rate(axi_b_clk, clk_round_rate(axi_b_clk, 130000000)); rate = clk_get_rate(ahb_clk); clk_set_rate(ahb_clk, clk_round_rate(ahb_clk, 130000000)); #endif dvfs_per_low_freq = 0; #ifndef DVFS_SW_WORKAROUND clk_set_parent(main_bus_clk, pll2); #endif }
static int __init mx5_pm_init(void) { if (gpc_dvfs_clk == NULL) gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs"); if (!IS_ERR(gpc_dvfs_clk)) { if (cpu_is_mx51()) suspend_set_ops(&mx5_suspend_ops); } else return -EPERM; return 0; }
void __init mx5_usbh1_init(void) { if (cpu_is_mx51()) { usbh1_config.phy_mode = FSL_USB2_PHY_ULPI; usbh1_config.transceiver = "isp1504"; usbh1_config.gpio_usb_active = gpio_usbh1_active; usbh1_config.gpio_usb_inactive = gpio_usbh1_inactive; } if (cpu_is_mx53() || cpu_is_mx50()) { mxc_usbh1_device.resource[0].start -= MX53_OFFSET; mxc_usbh1_device.resource[0].end -= MX53_OFFSET; } mxc_register_device(&mxc_usbh1_device, &usbh1_config); usbh1_config.wakeup_pdata = &usbh1_wakeup_config; mxc_register_device(&mxc_usbh1_wakeup_device, &usbh1_wakeup_config); }
static int fsl_usb_host_init_ext(struct platform_device *pdev) { int ret; struct clk *usb_clk; if (cpu_is_mx53()) { usb_clk = clk_get(NULL, "usboh3_clk"); clk_enable(usb_clk); clk_put(usb_clk); usb_clk = clk_get(&pdev->dev, "usb_phy2_clk"); clk_enable(usb_clk); clk_put(usb_clk); /*derive clock from oscillator */ usb_clk = clk_get(NULL, "usb_utmi_clk"); clk_disable(usb_clk); clk_put(usb_clk); } else if (cpu_is_mx50()) { usb_clk = clk_get(&pdev->dev, "usb_phy2_clk"); clk_enable(usb_clk); clk_put(usb_clk); } ret = fsl_usb_host_init(pdev); if (ret) return ret; if (cpu_is_mx51()) { /* setback USBH1_STP to be function */ mxc_request_iomux(MX51_PIN_USBH1_STP, IOMUX_CONFIG_ALT0); mxc_iomux_set_pad(MX51_PIN_USBH1_STP, PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS | PAD_CTL_DRV_VOT_LOW); gpio_free(IOMUX_TO_GPIO(MX51_PIN_USBH1_STP)); } /* disable remote wakeup irq */ USBCTRL &= ~UCTRL_H1WIE; return 0; }
static void fsl_usb_host_uninit_ext(struct fsl_usb2_platform_data *pdata) { if (cpu_is_mx53()) { clk_disable(usb_oh3_clk); clk_put(usb_oh3_clk); clk_disable(usb_phy2_clk); clk_put(usb_phy2_clk); } else if (cpu_is_mx50()) { clk_disable(usb_phy2_clk); clk_put(usb_phy2_clk); } else if (cpu_is_mx51()) { clk_disable(usb_oh3_clk); clk_put(usb_oh3_clk); } fsl_usb_host_uninit(pdata); /* usb_ahb_clk will be disabled at usb_common.c */ clk_put(usb_ahb_clk); }
/****************************************************************************** * * CAUTION: NONE * * MODIFICATION HISTORY: * * Date Person Change * 30/07/2003 MW Initial Creation ******************************************************************************/ int sah_Intr_Init(wait_queue_head_t * wait_queue) { #ifdef DIAG_DRV_INTERRUPT char err_string[200]; #endif int result; int irq_sah = MX53_INT_SAHARA_H0; if (cpu_is_mx51()) irq_sah = MX51_MXC_INT_SAHARA_H0; #ifdef KERNEL_TEST SAHARA_INT_PTR = sah_Intr_Top_Half; #endif /* Set queue used by the interrupt handler to match the driver interface */ int_queue = wait_queue; /* Request use of the Interrupt line. */ result = request_irq(irq_sah, sah_Intr_Top_Half, 0, SAHARA_NAME, NULL); #ifdef DIAG_DRV_INTERRUPT if (result != 0) { sprintf(err_string, "Cannot use SAHARA interrupt line %d. " "request_irq() return code is %i.", irq_sah, result); LOG_KDIAG(err_string); } else { sprintf(err_string, "SAHARA driver registered for interrupt %d. ", irq_sah); LOG_KDIAG(err_string); } #endif return result; }
static void usbh2_set_ulpi_xcvr(void) { u32 tmp; pr_debug("%s\n", __func__); UH2_USBCMD &= ~UCMD_RUN_STOP; while (UH2_USBCMD & UCMD_RUN_STOP) ; UH2_USBCMD |= UCMD_RESET; while (UH2_USBCMD & UCMD_RESET) USBCTRL_HOST2 &= ~(UCTRL_H2SIC_MASK | UCTRL_BPE); USBCTRL_HOST2 &= ~UCTRL_H2WIE; /* wakeup intr enable */ USBCTRL_HOST2 &= ~UCTRL_H2UIE; /* ULPI intr enable */ USB_CTRL_1 |= USB_CTRL_UH2_EXT_CLK_EN; if (cpu_is_mx53()) USB_CTRL_1 |= USB_CTRL_UH2_CLK_FROM_ULPI_PHY; if (cpu_is_mx51())/* not tested */ USBCTRL_HOST2 |= (1 << 12); /* must set ULPI phy before turning off clock */ tmp = UH2_PORTSC1 & ~PORTSC_PTS_MASK; tmp |= PORTSC_PTS_ULPI; UH2_PORTSC1 = tmp; if (cpu_is_mx53()) { /* turn off the internal 60MHZ clk */ USB_CLKONOFF_CTRL |= (1 << 21); } UH2_USBCMD |= UCMD_RESET; /* reset the controller */ /* allow controller to reset, and leave time for * the ULPI transceiver to reset too. */ msleep(100); /* Turn off the usbpll for ulpi tranceivers */ clk_disable(usb_clk); }
static int utp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int cpu_id = 0; switch (cmd) { case UTP_GET_CPU_ID: /* Currently, it only supports below SoC for manufacture tool * The naming rule * 1. The numberic for SoC string * 2. If there is next SoC version, and the corresponding utp * operation will be differ, then, need to add '1' next to SoC * name. Such as the next 50 SoC version is: cpu_is = 501 */ #ifdef CONFIG_ARCH_MXS if (cpu_is_mx23()) cpu_id = 23; else if (cpu_is_mx28()) cpu_id = 28; #endif #ifdef CONFIG_ARCH_MXC if (cpu_is_mx25()) cpu_id = 25; else if (cpu_is_mx35()) cpu_id = 35; else if (cpu_is_mx51()) cpu_id = 51; else if (cpu_is_mx53()) cpu_id = 53; else if (cpu_is_mx50()) cpu_id = 50; #endif return put_user(cpu_id, (int __user *)arg); default: return -ENOIOCTLCMD; } }
void fsl_usb_host_uninit(struct fsl_usb2_platform_data *pdata) { pr_debug("%s\n", __func__); if (pdata->xcvr_ops && pdata->xcvr_ops->uninit) pdata->xcvr_ops->uninit(pdata->xcvr_ops); pdata->regs = NULL; pdata->gpio_usb_inactive(); if (pdata->xcvr_type == PORTSC_PTS_SERIAL) { /* Workaround an IC issue for 2.6.26 kernal: * when turn off root hub port power, EHCI set * PORTSC reserved bits to be 0, but PTS with 0 * means UTMI interface, so here force the Host2 * port use the internal 60Mhz. */ if (cpu_is_mx35()) USBCTRL |= UCTRL_XCSH2; clk_disable(usb_clk); } /* disable board power supply for xcvr */ if (pdata->xcvr_pwr) { if (pdata->xcvr_pwr->regu1) regulator_disable(pdata->xcvr_pwr->regu1); if (pdata->xcvr_pwr->regu2) regulator_disable(pdata->xcvr_pwr->regu2); } if (cpu_is_mx51()) { usb_clk = clk_get(NULL, "usboh3_clk"); clk_disable(usb_clk); clk_put(usb_clk); } }
void fsl_usb_host_uninit(struct fsl_usb2_platform_data *pdata) { pr_debug("%s\n", __func__); if (pdata->xcvr_ops && pdata->xcvr_ops->uninit) pdata->xcvr_ops->uninit(pdata->xcvr_ops); pdata->regs = NULL; pdata->gpio_usb_inactive(); if (pdata->xcvr_type == PORTSC_PTS_SERIAL) clk_disable(usb_clk); else if ((pdata->xcvr_type == PORTSC_PTS_ULPI) && (machine_is_mx31_3ds())) { usbh2_put_xcvr_power(&(pdata->xcvr_pwr->usb_pdev->dev)); kfree(pdata->xcvr_pwr); } if (cpu_is_mx51()) { usb_clk = clk_get(NULL, "usboh3_clk"); clk_disable(usb_clk); clk_put(usb_clk); } }
static int ehci_mxc_drv_probe(struct platform_device *pdev) { struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data; struct usb_hcd *hcd; struct resource *res; int irq, ret; unsigned int flags; struct ehci_mxc_priv *priv; struct device *dev = &pdev->dev; struct ehci_hcd *ehci; dev_info(&pdev->dev, "initializing i.MX USB Controller\n"); if (!pdata) { dev_err(dev, "No platform data given, bailing out.\n"); return -EINVAL; } irq = platform_get_irq(pdev, 0); hcd = usb_create_hcd(&ehci_mxc_hc_driver, dev, dev_name(dev)); if (!hcd) return -ENOMEM; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { ret = -ENOMEM; goto err_alloc; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "Found HC with no register addr. Check setup!\n"); ret = -ENODEV; goto err_get_resource; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dev_dbg(dev, "controller already in use\n"); ret = -EBUSY; goto err_request_mem; } hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_err(dev, "error mapping memory\n"); ret = -EFAULT; goto err_ioremap; } /* enable clocks */ priv->usbclk = clk_get(dev, "usb"); if (IS_ERR(priv->usbclk)) { ret = PTR_ERR(priv->usbclk); goto err_clk; } clk_enable(priv->usbclk); if (!cpu_is_mx35() && !cpu_is_mx25()) { priv->ahbclk = clk_get(dev, "usb_ahb"); if (IS_ERR(priv->ahbclk)) { ret = PTR_ERR(priv->ahbclk); goto err_clk_ahb; } clk_enable(priv->ahbclk); } /* "dr" device has its own clock on i.MX51 */ if (cpu_is_mx51() && (pdev->id == 0)) { priv->phy1clk = clk_get(dev, "usb_phy1"); if (IS_ERR(priv->phy1clk)) { ret = PTR_ERR(priv->phy1clk); goto err_clk_phy; } clk_enable(priv->phy1clk); } /* call platform specific init function */ if (pdata->init) { ret = pdata->init(pdev); if (ret) { dev_err(dev, "platform init failed\n"); goto err_init; } /* platforms need some time to settle changed IO settings */ mdelay(10); } ehci = hcd_to_ehci(hcd); /* EHCI registers start at offset 0x100 */ ehci->caps = hcd->regs + 0x100; ehci->regs = hcd->regs + 0x100 + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); /* set up the PORTSCx register */ ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]); /* is this really needed? */ msleep(10); /* Initialize the transceiver */ if (pdata->otg) { pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET; ret = otg_init(pdata->otg); if (ret) { dev_err(dev, "unable to init transceiver, probably missing\n"); ret = -ENODEV; goto err_add; } ret = otg_set_vbus(pdata->otg, 1); if (ret) { dev_err(dev, "unable to enable vbus on transceiver\n"); goto err_add; } } priv->hcd = hcd; platform_set_drvdata(pdev, priv); ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (ret) goto err_add; if (pdata->otg) { /* * efikamx and efikasb have some hardware bug which is * preventing usb to work unless CHRGVBUS is set. * It's in violation of USB specs */ if (machine_is_mx51_efikamx() || machine_is_mx51_efikasb()) { flags = otg_io_read(pdata->otg, ULPI_OTG_CTRL); flags |= ULPI_OTG_CTRL_CHRGVBUS; ret = otg_io_write(pdata->otg, flags, ULPI_OTG_CTRL); if (ret) { dev_err(dev, "unable to set CHRVBUS\n"); goto err_add; } } } return 0; err_add: if (pdata && pdata->exit) pdata->exit(pdev); err_init: if (priv->phy1clk) { clk_disable(priv->phy1clk); clk_put(priv->phy1clk); } err_clk_phy: if (priv->ahbclk) { clk_disable(priv->ahbclk); clk_put(priv->ahbclk); } err_clk_ahb: clk_disable(priv->usbclk); clk_put(priv->usbclk); err_clk: iounmap(hcd->regs); err_ioremap: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err_request_mem: err_get_resource: kfree(priv); err_alloc: usb_put_hcd(hcd); return ret; }
int mxc_initialize_usb_hw(int port, unsigned int flags) { unsigned int v; #if defined(CONFIG_ARCH_MX25) if (cpu_is_mx25()) { v = readl(MX25_IO_ADDRESS(MX25_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); switch (port) { case 0: /* OTG port */ v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_OTG_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX35_OTG_PM_BIT; break; case 1: /* H1 port */ v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT | MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_H1_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX35_H1_PM_BIT; if (!(flags & MXC_EHCI_TTL_ENABLED)) v |= MX35_H1_TLL_BIT; if (flags & MXC_EHCI_INTERNAL_PHY) v |= MX35_H1_USBTE_BIT; if (flags & MXC_EHCI_IPPUE_DOWN) v |= MX35_H1_IPPUE_DOWN_BIT; if (flags & MXC_EHCI_IPPUE_UP) v |= MX35_H1_IPPUE_UP_BIT; break; default: return -EINVAL; } writel(v, MX25_IO_ADDRESS(MX25_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); return 0; } #endif /* CONFIG_ARCH_MX25 */ #if defined(CONFIG_ARCH_MX3) if (cpu_is_mx31()) { v = readl(MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); switch (port) { case 0: /* OTG port */ v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_OTG_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX31_OTG_PM_BIT; break; case 1: /* H1 port */ v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H1_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX31_H1_PM_BIT; if (!(flags & MXC_EHCI_TTL_ENABLED)) v |= MX31_H1_DT_BIT; break; case 2: /* H2 port */ v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H2_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX31_H2_PM_BIT; if (!(flags & MXC_EHCI_TTL_ENABLED)) v |= MX31_H2_DT_BIT; break; default: return -EINVAL; } writel(v, MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); return 0; } if (cpu_is_mx35()) { v = readl(MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); switch (port) { case 0: /* OTG port */ v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_OTG_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX35_OTG_PM_BIT; break; case 1: /* H1 port */ v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT | MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX35_H1_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX35_H1_PM_BIT; if (!(flags & MXC_EHCI_TTL_ENABLED)) v |= MX35_H1_TLL_BIT; if (flags & MXC_EHCI_INTERNAL_PHY) v |= MX35_H1_USBTE_BIT; if (flags & MXC_EHCI_IPPUE_DOWN) v |= MX35_H1_IPPUE_DOWN_BIT; if (flags & MXC_EHCI_IPPUE_UP) v |= MX35_H1_IPPUE_UP_BIT; break; default: return -EINVAL; } writel(v, MX35_IO_ADDRESS(MX35_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); return 0; } #endif /* CONFIG_ARCH_MX3 */ #ifdef CONFIG_MACH_MX27 if (cpu_is_mx27()) { /* On i.MX27 we can use the i.MX31 USBCTRL bits, they * are identical */ v = readl(MX27_IO_ADDRESS(MX27_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); switch (port) { case 0: /* OTG port */ v &= ~(MX31_OTG_SIC_MASK | MX31_OTG_PM_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_OTG_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX31_OTG_PM_BIT; break; case 1: /* H1 port */ v &= ~(MX31_H1_SIC_MASK | MX31_H1_PM_BIT | MX31_H1_DT_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H1_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX31_H1_PM_BIT; if (!(flags & MXC_EHCI_TTL_ENABLED)) v |= MX31_H1_DT_BIT; break; case 2: /* H2 port */ v &= ~(MX31_H2_SIC_MASK | MX31_H2_PM_BIT | MX31_H2_DT_BIT); v |= (flags & MXC_EHCI_INTERFACE_MASK) << MX31_H2_SIC_SHIFT; if (!(flags & MXC_EHCI_POWER_PINS_ENABLED)) v |= MX31_H2_PM_BIT; if (!(flags & MXC_EHCI_TTL_ENABLED)) v |= MX31_H2_DT_BIT; break; default: return -EINVAL; } writel(v, MX27_IO_ADDRESS(MX27_OTG_BASE_ADDR + USBCTRL_OTGBASE_OFFSET)); return 0; } #endif /* CONFIG_MACH_MX27 */ #ifdef CONFIG_ARCH_MX51 if (cpu_is_mx51()) { void __iomem *usb_base; u32 usbotg_base; u32 usbother_base; int ret = 0; usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K); switch (port) { case 0: /* OTG port */ usbotg_base = usb_base + MXC_OTG_OFFSET; break; case 1: /* Host 1 port */ usbotg_base = usb_base + MXC_H1_OFFSET; break; default: printk(KERN_ERR"%s no such port %d\n", __func__, port); ret = -ENOENT; goto error; } usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET; switch (port) { case 0: /*OTG port */ if (flags & MXC_EHCI_INTERNAL_PHY) { v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); if (flags & MXC_EHCI_POWER_PINS_ENABLED) v |= (MXC_OTG_PHYCTRL_OC_DIS_BIT | MXC_OTG_UCTRL_OPM_BIT); /* OC/USBPWR is not used */ else v &= ~(MXC_OTG_PHYCTRL_OC_DIS_BIT | MXC_OTG_UCTRL_OPM_BIT); /* OC/USBPWR is used */ __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET); if (flags & MXC_EHCI_WAKEUP_ENABLED) v |= MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup enable */ else v &= ~MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup disable */ __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET); } break; case 1: /* Host 1 */ /*Host ULPI */ v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET); if (flags & MXC_EHCI_WAKEUP_ENABLED) v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);/* HOST1 wakeup/ULPI intr disable */ else v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);/* HOST1 wakeup/ULPI intr disable */ if (flags & MXC_EHCI_POWER_PINS_ENABLED) v &= ~MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/ else v |= MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/ __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET); v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); if (flags & MXC_EHCI_POWER_PINS_ENABLED) v &= ~MXC_H1_OC_DIS_BIT; /* OC is used */ else v |= MXC_H1_OC_DIS_BIT; /* OC is not used */ __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET); v = __raw_readl(usbotg_base + MXC_USBCMD_OFFSET); if (flags & MXC_EHCI_ITC_NO_THRESHOLD) /* Interrupt Threshold Control:Immediate (no threshold) */ v &= MXC_UCMD_ITC_NO_THRESHOLD_MASK; __raw_writel(v, usbotg_base + MXC_USBCMD_OFFSET); break; } error: iounmap(usb_base); return ret; } #endif printk(KERN_WARNING "%s() unable to setup USBCONTROL for this CPU\n", __func__); return -EINVAL; }
int set_high_bus_freq(int high_bus_freq) { u32 reg; if (bus_freq_scaling_initialized) { mutex_lock(&bus_freq_mutex); /* * If the CPU freq is 800MHz, set the bus to the high * setpoint (133MHz) and DDR to 200MHz. */ if ((clk_get_rate(cpu_clk) > cpu_wp_tbl[cpu_wp_nr - 1].cpu_rate) || lp_high_freq) high_bus_freq = 1; stop_sdram_autogating(); if (low_bus_freq_mode) { /* Relock PLL3 to 133MHz */ if (cpu_is_mx50()) exit_lpapm_mode_mx50(high_bus_freq); else if (cpu_is_mx51()) exit_lpapm_mode_mx51(); else exit_lpapm_mode_mx53(); start_dvfs_per(); } if (bus_freq_scaling_is_active) { if (!high_bus_freq_mode && high_bus_freq) { if (cpu_is_mx50()) { if (med_bus_freq_mode) { /* Increase SYS_CLK */ reg = __raw_readl(MXC_CCM_CLK_SYS); reg &= ~MXC_CCM_CLK_SYS_DIV_PLL_MASK; reg |= 4 << MXC_CCM_CLK_SYS_DIV_PLL_OFFSET; __raw_writel(reg, MXC_CCM_CLK_SYS); /* Set the dividers to the default dividers */ reg = __raw_readl(MXC_CCM_CBCDR); reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK | MXC_CCM_CBCDR_AXI_B_PODF_MASK | MXC_CCM_CBCDR_AHB_PODF_MASK | MX50_CCM_CBCDR_WEIM_PODF_MASK); reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET |1 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET |2 << MXC_CCM_CBCDR_AHB_PODF_OFFSET |0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET); __raw_writel(reg, MXC_CCM_CBCDR); while (__raw_readl(MXC_CCM_CDHIPR) & 0xF) udelay(10); } } else { clk_set_rate(ahb_clk, clk_round_rate(ahb_clk, lp_normal_rate)); clk_set_rate(ddr_hf_clk, clk_round_rate(ddr_hf_clk, ddr_normal_rate)); } /* Set to the high setpoint. */ high_bus_freq_mode = 1; low_bus_freq_mode = 0; med_bus_freq_mode = 0; } else if (!med_bus_freq_mode && !high_bus_freq) { if (cpu_is_mx50()) { /* Set the dividers to the medium setpoint dividers */ reg = __raw_readl(MXC_CCM_CBCDR); reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK | MXC_CCM_CBCDR_AXI_B_PODF_MASK | MXC_CCM_CBCDR_AHB_PODF_MASK | MX50_CCM_CBCDR_WEIM_PODF_MASK); reg |= (1 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET |3 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET |5 << MXC_CCM_CBCDR_AHB_PODF_OFFSET |0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET); __raw_writel(reg, MXC_CCM_CBCDR); while (__raw_readl(MXC_CCM_CDHIPR) & 0xF) udelay(10); /* Reduce SYS_CLK */ reg = __raw_readl(MXC_CCM_CLK_SYS); reg &= ~MXC_CCM_CLK_SYS_DIV_PLL_MASK; reg |= 8 << MXC_CCM_CLK_SYS_DIV_PLL_OFFSET; __raw_writel(reg, MXC_CCM_CLK_SYS); } else { if (cpu_is_mx51()) clk_set_rate(ddr_hf_clk, clk_round_rate( ddr_hf_clk, ddr_low_rate)); clk_set_rate(ahb_clk, clk_round_rate( ahb_clk, lp_med_rate)); } /* Set to the medium setpoint. */ high_bus_freq_mode = 0; low_bus_freq_mode = 0; med_bus_freq_mode = 1; } if (cpu_is_mx50()) { if (med_bus_freq_mode && (cur_ddr_rate != ddr_med_rate)) set_ddr_freq(ddr_med_rate); if (high_bus_freq_mode && (cur_ddr_rate != ddr_normal_rate)) set_ddr_freq(ddr_normal_rate); } } start_sdram_autogating(); mutex_unlock(&bus_freq_mutex); } return 0; }
/* set cpu low power mode before WFI instruction */ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode) { u32 plat_lpc, arm_srpgcr, ccm_clpcr; u32 empgc0 = 0; u32 empgc1 = 0; int stop_mode = 0; /* always allow platform to issue a deep sleep mode request */ plat_lpc = __raw_readl(arm_plat_base + MXC_CORTEXA8_PLAT_LPC) & ~(MXC_CORTEXA8_PLAT_LPC_DSM); ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK); arm_srpgcr = __raw_readl(MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR); if (!cpu_is_mx53()) { empgc0 = __raw_readl(MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR); empgc1 = __raw_readl(MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR); } switch (mode) { case WAIT_CLOCKED: break; case WAIT_UNCLOCKED: ccm_clpcr |= (0x1 << MXC_CCM_CLPCR_LPM_OFFSET); break; case WAIT_UNCLOCKED_POWER_OFF: case STOP_POWER_OFF: plat_lpc |= MXC_CORTEXA8_PLAT_LPC_DSM | MXC_CORTEXA8_PLAT_LPC_DBG_DSM; if (mode == WAIT_UNCLOCKED_POWER_OFF) { ccm_clpcr |= (0x1 << MXC_CCM_CLPCR_LPM_OFFSET); ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY; ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS; stop_mode = 0; } else { ccm_clpcr |= (0x2 << MXC_CCM_CLPCR_LPM_OFFSET); ccm_clpcr |= (0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET); ccm_clpcr |= MXC_CCM_CLPCR_VSTBY; ccm_clpcr |= MXC_CCM_CLPCR_SBYOS; stop_mode = 1; } arm_srpgcr |= MXC_SRPGCR_PCR; if (stop_mode && !cpu_is_mx53()) { empgc0 |= MXC_SRPGCR_PCR; empgc1 |= MXC_SRPGCR_PCR; } if (tzic_enable_wake(1) != 0) return; break; case STOP_POWER_ON: ccm_clpcr |= (0x2 << MXC_CCM_CLPCR_LPM_OFFSET); break; default: printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode); return; } __raw_writel(plat_lpc, arm_plat_base + MXC_CORTEXA8_PLAT_LPC); __raw_writel(ccm_clpcr, MXC_CCM_CLPCR); if (cpu_is_mx51() || (mx53_revision() >= IMX_CHIP_REVISION_2_0) || (mx50_revision() >= IMX_CHIP_REVISION_1_1)) __raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR); /* Enable NEON SRPG for all but MX50TO1.0. */ if (!(mx50_revision() == IMX_CHIP_REVISION_1_0)) __raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR); if (stop_mode && !cpu_is_mx53()) { __raw_writel(empgc0, MXC_SRPG_EMPGC0_SRPGCR); __raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR); } }
/* * SSI DAI format configuration. * Should only be called when port is inactive (i.e. SSIEN = 0). * Note: We don't use the I2S modes but instead manually configure the * SSI for I2S. */ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) { struct imx_ssi *priv = (struct imx_ssi *)cpu_dai->private_data; void __iomem *ioaddr = priv->ioaddr; u32 stcr = 0, srcr = 0, scr; scr = __raw_readl(ioaddr + SSI_SCR) & ~(SSI_SCR_SYN | SSI_SCR_NET); if (scr & SSI_SCR_SSIEN) return 0; /* DAI mode */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: /* data on rising edge of bclk, frame low 1clk before data */ stcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0; srcr |= SSI_SRCR_RFSI | SSI_SRCR_REFS | SSI_SRCR_RXBIT0; break; case SND_SOC_DAIFMT_LEFT_J: /* data on rising edge of bclk, frame high with data */ stcr |= SSI_STCR_TXBIT0; srcr |= SSI_SRCR_RXBIT0; break; case SND_SOC_DAIFMT_DSP_B: /* data on rising edge of bclk, frame high with data */ stcr |= SSI_STCR_TFSL; srcr |= SSI_SRCR_RFSL; break; case SND_SOC_DAIFMT_DSP_A: /* data on rising edge of bclk, frame high 1clk before data */ stcr |= SSI_STCR_TFSL | SSI_STCR_TEFS; srcr |= SSI_SRCR_RFSL | SSI_SRCR_REFS; break; } /* DAI clock inversion */ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_IB_IF: stcr &= ~(SSI_STCR_TSCKP | SSI_STCR_TFSI); srcr &= ~(SSI_SRCR_RSCKP | SSI_SRCR_RFSI); break; case SND_SOC_DAIFMT_IB_NF: stcr |= SSI_STCR_TFSI; stcr &= ~SSI_STCR_TSCKP; srcr |= SSI_SRCR_RFSI; srcr &= ~SSI_SRCR_RSCKP; break; case SND_SOC_DAIFMT_NB_IF: stcr &= ~SSI_STCR_TFSI; stcr |= SSI_STCR_TSCKP; srcr &= ~SSI_SRCR_RFSI; srcr |= SSI_SRCR_RSCKP; break; case SND_SOC_DAIFMT_NB_NF: stcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP; srcr |= SSI_SRCR_RFSI | SSI_SRCR_RSCKP; break; } /* DAI clock master masks */ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: stcr |= SSI_STCR_TFDIR | SSI_STCR_TXDIR; if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S) && priv->network_mode) { scr &= ~SSI_SCR_I2S_MODE_MASK; scr |= SSI_SCR_I2S_MODE_MSTR; } break; case SND_SOC_DAIFMT_CBM_CFS: stcr |= SSI_STCR_TFDIR; srcr |= SSI_SRCR_RFDIR; break; case SND_SOC_DAIFMT_CBS_CFM: stcr |= SSI_STCR_TXDIR; srcr |= SSI_SRCR_RXDIR; break; case SND_SOC_DAIFMT_CBM_CFM: if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S) && priv->network_mode) { scr &= ~SSI_SCR_I2S_MODE_MASK; scr |= SSI_SCR_I2S_MODE_SLAVE; } break; } /* sync */ if (priv->sync_mode) scr |= SSI_SCR_SYN; /* tdm - only for stereo atm */ if (priv->network_mode) scr |= SSI_SCR_NET; #ifdef CONFIG_MXC_SSI_DUAL_FIFO if (cpu_is_mx51() || cpu_is_mx53()) { stcr |= SSI_STCR_TFEN1; srcr |= SSI_SRCR_RFEN1; scr |= SSI_SCR_TCH_EN; } #endif __raw_writel(stcr, ioaddr + SSI_STCR); __raw_writel(srcr, ioaddr + SSI_SRCR); __raw_writel(scr, ioaddr + SSI_SCR); SSI_DUMP(); return 0; }
static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pdata) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data; struct clk *clk; int err; clk = clk_get(mmc_dev(host->mmc), NULL); if (IS_ERR(clk)) { dev_err(mmc_dev(host->mmc), "clk err\n"); return PTR_ERR(clk); } clk_enable(clk); pltfm_host->clk = clk; if (cpu_is_mx35() || cpu_is_mx51()) host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; if (cpu_is_mx25() || cpu_is_mx35()) { /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */ host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK; /* write_protect can't be routed to controller, use gpio */ sdhci_esdhc_ops.get_ro = esdhc_pltfm_get_ro; } if (boarddata) { err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, "ESDHC_WP"); if (err) { dev_warn(mmc_dev(host->mmc), "no write-protect pin available!\n"); boarddata->wp_gpio = err; } err = gpio_request_one(boarddata->cd_gpio, GPIOF_IN, "ESDHC_CD"); if (err) { dev_warn(mmc_dev(host->mmc), "no card-detect pin available!\n"); goto no_card_detect_pin; } /* i.MX5x has issues to be researched */ if (!cpu_is_mx25() && !cpu_is_mx35()) goto not_supported; err = request_irq(gpio_to_irq(boarddata->cd_gpio), cd_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, mmc_hostname(host->mmc), host); if (err) { dev_warn(mmc_dev(host->mmc), "request irq error\n"); goto no_card_detect_irq; } sdhci_esdhc_ops.write_l = esdhc_writel_le; sdhci_esdhc_ops.read_l = esdhc_readl_le; /* Now we have a working card_detect again */ host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; } return 0; no_card_detect_irq: gpio_free(boarddata->cd_gpio); no_card_detect_pin: boarddata->cd_gpio = err; not_supported: return 0; }