static int __init mxc_init_uart(void) { if (cpu_is_mx53() || cpu_is_mx50()) { mxc_uart_resources1[0].start -= 0x20000000; mxc_uart_resources1[0].end -= 0x20000000; mxc_uart_resources2[0].start -= 0x20000000; mxc_uart_resources2[0].end -= 0x20000000; mxc_uart_resources3[0].start -= 0x20000000; mxc_uart_resources3[0].end -= 0x20000000; mxc_uart_resources4[0].start -= 0x20000000; mxc_uart_resources4[0].end -= 0x20000000; mxc_uart_resources5[0].start -= 0x20000000; mxc_uart_resources5[0].end -= 0x20000000; } /* Register all the MXC UART platform device structures */ /* For Tequila, register only uart1, this will help PM */ platform_device_register(&mxc_uart_device1); if (!mx50_board_is(BOARD_ID_TEQUILA)) { platform_device_register(&mxc_uart_device2); platform_device_register(&mxc_uart_device3); platform_device_register(&mxc_uart_device4); if (cpu_is_mx53()) { platform_device_register(&mxc_uart_device5); } } return 0; }
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; }
void set_ddr_freq(int ddr_rate) { unsigned long flags; unsigned int ret = 0; spin_lock_irqsave(&ddr_freq_lock, flags); if (cpu_is_mx50()) ret = update_ddr_freq(ddr_rate); #if 1 { unsigned int reg; printk(KERN_NOTICE "set_ddr_freq ddr_rate =%d ret = %d \n",ddr_rate, ret); reg = __raw_readl(MXC_CCM_CLK_DDR); printk(KERN_NOTICE "after ddr divider = 0x%x \n",reg&0x3f); } #endif spin_unlock_irqrestore(&ddr_freq_lock, flags); if (!ret) cur_ddr_rate = ddr_rate; udelay(100); }
int usbotg_init(struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; struct fsl_xcvr_ops *xops; pr_debug("%s: pdev=0x%p pdata=0x%p\n", __func__, pdev, pdata); xops = fsl_usb_get_xcvr(pdata->transceiver); if (!xops) { printk(KERN_ERR "DR transceiver ops missing\n"); return -EINVAL; } pdata->xcvr_ops = xops; pdata->xcvr_type = xops->xcvr_type; pdata->pdev = pdev; if (fsl_check_usbclk() != 0) return -EINVAL; if (!mxc_otg_used) { if (cpu_is_mx50()) /* Turn on AHB CLK for OTG*/ USB_CLKONOFF_CTRL &= ~OTG_AHBCLK_OFF; pr_debug("%s: grab pins\n", __func__); if (pdata->gpio_usb_active && pdata->gpio_usb_active()) return -EINVAL; if (clk_enable(usb_clk)) { printk(KERN_ERR "clk_enable(usb_clk) failed\n"); return -EINVAL; } if (xops->init) xops->init(xops); UOG_PORTSC1 = UOG_PORTSC1 & ~PORTSC_PHCD; if (xops->xcvr_type == PORTSC_PTS_SERIAL) { if (pdata->operating_mode == FSL_USB2_DR_HOST) { otg_set_serial_host(); /* need reset */ UOG_USBCMD |= UCMD_RESET; msleep(100); } else if (pdata->operating_mode == FSL_USB2_DR_DEVICE) otg_set_serial_peripheral(); otg_set_serial_xcvr(); } else if (xops->xcvr_type == PORTSC_PTS_ULPI) { otg_set_ulpi_xcvr(); } else if (xops->xcvr_type == PORTSC_PTS_UTMI) { otg_set_utmi_xcvr(); } } if (usb_register_remote_wakeup(pdev)) pr_debug("DR is not a wakeup source.\n"); mxc_otg_used++; pr_debug("%s: success\n", __func__); return 0; }
void start_sdram_autogating() { if (cpu_is_mx50()) return; if (sdram_autogating_paused) { enable(); sdram_autogating_paused = 0; } }
/*! * This function puts the CPU into idle mode. It is called by default_idle() * in process.c file. */ void arch_idle(void) { if (likely(!mxc_jtag_enabled)) { if (ddr_clk == NULL) ddr_clk = clk_get(NULL, "ddr_clk"); if (gpc_dvfs_clk == NULL) gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs_clk"); /* gpc clock is needed for SRPG */ clk_enable(gpc_dvfs_clk); mxc_cpu_lp_set(arch_idle_mode); if (cpu_is_mx50() && (clk_get_usecount(ddr_clk) == 0)) { memcpy(wait_in_iram_base, mx50_wait, SZ_4K); wait_in_iram = (void *)wait_in_iram_base; if (low_bus_freq_mode) { u32 reg, cpu_podf; reg = __raw_readl(apll_base + 0x50); reg = 0x120490; __raw_writel(reg, apll_base + 0x50); reg = __raw_readl(apll_base + 0x80); reg |= 1; __raw_writel(reg, apll_base + 0x80); /* Move ARM to be sourced from 24MHz XTAL. * when ARM is in WFI. */ if (pll1_sw_clk == NULL) pll1_sw_clk = clk_get(NULL, "pll1_sw_clk"); if (osc == NULL) osc = clk_get(NULL, "lp_apm"); if (pll1_main_clk == NULL) pll1_main_clk = clk_get(NULL, "pll1_main_clk"); clk_set_parent(pll1_sw_clk, osc); /* Set the ARM-PODF divider to 1. */ cpu_podf = __raw_readl(MXC_CCM_CACRR); __raw_writel(0x01, MXC_CCM_CACRR); wait_in_iram(ccm_base, databahn_base); /* Set the ARM-POD divider back * to the original. */ __raw_writel(cpu_podf, MXC_CCM_CACRR); clk_set_parent(pll1_sw_clk, pll1_main_clk); } else wait_in_iram(ccm_base, databahn_base); } else cpu_do_idle(); clk_disable(gpc_dvfs_clk); clk_put(ddr_clk); } }
/* * Returns: * the silicon revision of the cpu * -EINVAL - not a mx50 */ int mx50_revision(void) { if (!cpu_is_mx50()) return -EINVAL; if (mx5_cpu_rev == -1) mx5_cpu_rev = get_mx50_srev(); return mx5_cpu_rev; }
void __init mx5_usbh2_init(void) { if (cpu_is_mx53() || cpu_is_mx50()) { mxc_usbh2_device.resource[0].start -= MX53_OFFSET; mxc_usbh2_device.resource[0].end -= MX53_OFFSET; } usbh2_config.wakeup_pdata = &usbh2_wakeup_config; mxc_register_device(&mxc_usbh2_device, &usbh2_config); mxc_register_device(&mxc_usbh2_wakeup_device, &usbh2_wakeup_config); }
/* * Returns: * the silicon revision of the cpu * -EINVAL - not a mx50 */ int mx50_revision(void) { if (!cpu_is_mx50()) return -EINVAL; if (cpu_silicon_rev == -1) cpu_silicon_rev = get_mx50_srev(); return cpu_silicon_rev; }
void stop_sdram_autogating() { if (cpu_is_mx50()) return; if (sdram_autogating_is_active) { sdram_autogating_paused = 1; disable(); } }
/*! * This function initializes the memory map. It is called during the * system startup to create static physical to virtual memory map for * the IO modules. */ void __init mx5_map_io(void) { int i; // mxc_iomux_v3_init(IO_ADDRESS(IOMUXC_BASE_ADDR)); /* Fixup the mappings for MX53 */ if (cpu_is_mx53() || cpu_is_mx50()) { for (i = 0; i < ARRAY_SIZE(mx5_io_desc); i++) mx5_io_desc[i].pfn -= __phys_to_pfn(0x20000000); } iotable_init(mx5_io_desc, ARRAY_SIZE(mx5_io_desc)); mxc_arch_reset_init(IO_ADDRESS(WDOG1_BASE_ADDR)); }
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 set_ddr_freq(int ddr_rate) { unsigned long flags; unsigned int ret = 0; spin_lock_irqsave(&ddr_freq_lock, flags); if (cpu_is_mx50()) ret = update_ddr_freq(ddr_rate); spin_unlock_irqrestore(&ddr_freq_lock, flags); if (!ret) cur_ddr_rate = ddr_rate; udelay(100); }
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) { struct clk *usb_clk; if (cpu_is_mx53()) { usb_clk = clk_get(NULL, "usboh3_clk"); clk_disable(usb_clk); clk_put(usb_clk); usb_clk = clk_get(&pdata->pdev->dev, "usb_phy2_clk"); clk_disable(usb_clk); clk_put(usb_clk); } else if (cpu_is_mx50()) { usb_clk = clk_get(&pdata->pdev->dev, "usb_phy2_clk"); clk_disable(usb_clk); clk_put(usb_clk); } fsl_usb_host_uninit(pdata); }
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); }
static ssize_t bus_freq_scaling_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { u32 reg; if (strncmp(buf, "1", 1) == 0) { if (dvfs_per_active()) { printk(KERN_INFO "bus frequency scaling cannot be\ enabled when DVFS-PER is active\n"); return size; } if (!cpu_is_mx50()) { /* Initialize DVFS-PODF to 0. */ reg = __raw_readl(MXC_CCM_CDCR); reg &= ~MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_MASK; __raw_writel(reg, MXC_CCM_CDCR); clk_set_parent(main_bus_clk, pll2); } bus_freq_scaling_is_active = 1; set_high_bus_freq(0); } else if (strncmp(buf, "0", 1) == 0) {
static int __init mxc_init_uart(void) { if (cpu_is_mx53() || cpu_is_mx50()) { mxc_uart_resources1[0].start -= 0x20000000; mxc_uart_resources1[0].end -= 0x20000000; mxc_uart_resources2[0].start -= 0x20000000; mxc_uart_resources2[0].end -= 0x20000000; mxc_uart_resources3[0].start -= 0x20000000; mxc_uart_resources3[0].end -= 0x20000000; mxc_uart_resources4[0].start -= 0x20000000; mxc_uart_resources4[0].end -= 0x20000000; mxc_uart_resources5[0].start -= 0x20000000; mxc_uart_resources5[0].end -= 0x20000000; } /* Register all the MXC UART platform device structures */ /* For Tequila, register only uart1, this will help PM */ platform_device_register(&mxc_uart_device1); return 0; }
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; } }
static void otg_set_utmi_xcvr(void) { u32 tmp; /* Stop then Reset */ UOG_USBCMD &= ~UCMD_RUN_STOP; while (UOG_USBCMD & UCMD_RUN_STOP) ; UOG_USBCMD |= UCMD_RESET; while ((UOG_USBCMD) & (UCMD_RESET)) ; if (cpu_is_mx53()) USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_OC_DIS; if (cpu_is_mx51()) { if (machine_is_mx51_3ds()) { /* OTG Polarity of Overcurrent is Low active */ USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_OC_POL; /* Enable OTG Overcurrent Event */ USB_PHY_CTR_FUNC &= ~USB_UTMI_PHYCTRL_OC_DIS; } else { /* BBG is not using OC */ USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_OC_DIS; } } else if (cpu_is_mx25()) { USBCTRL |= UCTRL_OCPOL; USBCTRL &= ~UCTRL_PP; } else if (cpu_is_mx50()) { USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_OC_DIS; } else { /* USBOTG_PWR low active */ USBCTRL &= ~UCTRL_PP; /* OverCurrent Polarity is Low Active */ USBCTRL &= ~UCTRL_OCPOL; if (cpu_is_mx35() && (imx_cpu_ver() < IMX_CHIP_REVISION_2_0)) /* OTG Lock Disable */ USBCTRL |= UCTRL_OLOCKD; } if (cpu_is_mx51()) USBCTRL &= ~UCTRL_OPM; /* OTG Power Mask */ USBCTRL &= ~UCTRL_OWIE; /* OTG Wakeup Intr Disable */ /* set UTMI xcvr */ tmp = UOG_PORTSC1 & ~PORTSC_PTS_MASK; tmp |= PORTSC_PTS_UTMI; UOG_PORTSC1 = tmp; if (cpu_is_mx51()) { /* Set the PHY clock to 19.2MHz */ USB_PHY_CTR_FUNC2 &= ~USB_UTMI_PHYCTRL2_PLLDIV_MASK; USB_PHY_CTR_FUNC2 |= 0x01; } /* Workaround an IC issue for ehci driver: * when turn off root hub port power, EHCI set * PORTSC reserved bits to be 0, but PTW with 0 * means 8 bits tranceiver width, here change * it back to be 16 bits and do PHY diable and * then enable. */ UOG_PORTSC1 |= PORTSC_PTW; if (cpu_is_mx35() || cpu_is_mx25()) { /* Enable UTMI interface in PHY control Reg */ USB_PHY_CTR_FUNC &= ~USB_UTMI_PHYCTRL_UTMI_ENABLE; USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_UTMI_ENABLE; } /* need to reset the controller here so that the ID pin * is correctly detected. */ /* Stop then Reset */ UOG_USBCMD &= ~UCMD_RUN_STOP; while (UOG_USBCMD & UCMD_RUN_STOP) ; UOG_USBCMD |= UCMD_RESET; while ((UOG_USBCMD) & (UCMD_RESET)) ; /* allow controller to reset, and leave time for * the ULPI transceiver to reset too. */ msleep(100); if (cpu_is_mx37()) { /* fix USB PHY Power Gating leakage issue for i.MX37 */ USB_PHY_CTR_FUNC &= ~USB_UTMI_PHYCTRL_CHGRDETON; USB_PHY_CTR_FUNC &= ~USB_UTMI_PHYCTRL_CHGRDETEN; } /* Turn off the usbpll for UTMI tranceivers */ clk_disable(usb_clk); }
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; }
static int __init post_cpu_init(void) { void __iomem *base; unsigned int reg; struct clk *gpcclk = clk_get(NULL, "gpc_dvfs_clk"); int iram_size = IRAM_SIZE; if (!cpu_is_mx5()) return 0; if (cpu_is_mx51()) { mipi_hsc_disable(); #if defined(CONFIG_MXC_SECURITY_SCC) || defined(CONFIG_MXC_SECURITY_SCC_MODULE) iram_size -= SCC_RAM_SIZE; #endif iram_init(MX51_IRAM_BASE_ADDR, iram_size); } else { iram_init(MX53_IRAM_BASE_ADDR, iram_size); } gpc_base = ioremap(MX53_BASE_ADDR(GPC_BASE_ADDR), SZ_4K); ccm_base = ioremap(MX53_BASE_ADDR(CCM_BASE_ADDR), SZ_4K); clk_enable(gpcclk); /* Setup the number of clock cycles to wait for SRPG * power up and power down requests. */ __raw_writel(0x010F0201, gpc_base + SRPG_ARM_PUPSCR); __raw_writel(0x010F0201, gpc_base + SRPG_NEON_PUPSCR); __raw_writel(0x00000008, gpc_base + SRPG_EMPGC0_PUPSCR); __raw_writel(0x00000008, gpc_base + SRPG_EMPGC1_PUPSCR); __raw_writel(0x01010101, gpc_base + SRPG_ARM_PDNSCR); __raw_writel(0x01010101, gpc_base + SRPG_NEON_PDNSCR); __raw_writel(0x00000018, gpc_base + SRPG_EMPGC0_PDNSCR); __raw_writel(0x00000018, gpc_base + SRPG_EMPGC1_PDNSCR); clk_disable(gpcclk); clk_put(gpcclk); /* Set ALP bits to 000. Set ALP_EN bit in Arm Memory Controller reg. */ arm_plat_base = ioremap(MX53_BASE_ADDR(ARM_BASE_ADDR), SZ_4K); reg = 0x8; __raw_writel(reg, arm_plat_base + CORTEXA8_PLAT_AMC); base = ioremap(MX53_BASE_ADDR(AIPS1_BASE_ADDR), SZ_4K); __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(MX53_BASE_ADDR(AIPS2_BASE_ADDR), SZ_4K); __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 (cpu_is_mx51() || cpu_is_mx53()) { /*Allow for automatic gating of the EMI internal clock. * If this is done, emi_intr CCGR bits should be set to 11. */ base = ioremap(MX53_BASE_ADDR(M4IF_BASE_ADDR), SZ_4K); reg = __raw_readl(base + 0x8c); reg &= ~0x1; __raw_writel(reg, base + 0x8c); iounmap(base); } if (cpu_is_mx50()) init_ddr_settings(); return 0; }
static int __init w1_setup(char *__unused) { enable_w1 = 1; return cpu_is_mx50(); }
/*! * This function puts the CPU into idle mode. It is called by default_idle() * in process.c file. */ void arch_idle(void) { if (likely(!mxc_jtag_enabled)) { if (ddr_clk == NULL) ddr_clk = clk_get(NULL, "ddr_clk"); if (gpc_dvfs_clk == NULL) gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs_clk"); /* gpc clock is needed for SRPG */ clk_enable(gpc_dvfs_clk); mxc_cpu_lp_set(arch_idle_mode); if (cpu_is_mx50() && (clk_get_usecount(ddr_clk) == 0)) { if (sys_clk == NULL) sys_clk = clk_get(NULL, "sys_clk"); if (low_bus_freq_mode) { u32 reg, cpu_podf; reg = __raw_readl(apll_base + 0x50); reg = 0x120490; __raw_writel(reg, apll_base + 0x50); reg = __raw_readl(apll_base + 0x80); reg |= 1; __raw_writel(reg, apll_base + 0x80); if (mx50_ddr_type != MX50_DDR2) { /* Move ARM to be sourced from 24MHz XTAL. * when ARM is in WFI. */ if (pll1_sw_clk == NULL) pll1_sw_clk = clk_get(NULL, "pll1_sw_clk"); if (osc == NULL) osc = clk_get(NULL, "lp_apm"); if (pll1_main_clk == NULL) pll1_main_clk = clk_get(NULL, "pll1_main_clk"); clk_set_parent(pll1_sw_clk, osc); /* Set the ARM-PODF divider to 1. */ cpu_podf = __raw_readl(MXC_CCM_CACRR); __raw_writel(0x01, MXC_CCM_CACRR); while (__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_ARM_PODF_BUSY) ; } wait_in_iram(ccm_base, databahn_base, clk_get_usecount(sys_clk)); if (mx50_ddr_type != MX50_DDR2) { /* Set the ARM-POD divider back * to the original. */ __raw_writel(cpu_podf, MXC_CCM_CACRR); while (__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_ARM_PODF_BUSY) ; clk_set_parent(pll1_sw_clk, pll1_main_clk); } } else wait_in_iram(ccm_base, databahn_base, clk_get_usecount(sys_clk)); } else if (cpu_is_mx53() && (clk_get_usecount(ddr_clk) == 0) && low_bus_freq_mode) { suspend_in_iram(suspend_param1, NULL, NULL); } else cpu_do_idle(); clk_disable(gpc_dvfs_clk); clk_put(ddr_clk); } }
static void usbh1_set_utmi_xcvr(void) { u32 tmp; /* Stop then Reset */ UH1_USBCMD &= ~UCMD_RUN_STOP; while (UH1_USBCMD & UCMD_RUN_STOP) ; UH1_USBCMD |= UCMD_RESET; while ((UH1_USBCMD) & (UCMD_RESET)) ; /* For OC and PWR, it is board level setting * The default setting is for mx53 evk */ USBCTRL &= ~UCTRL_H1PM; /* Host1 Power Mask */ USBCTRL &= ~UCTRL_H1WIE; /* Host1 Wakeup Intr Disable */ USB_PHY_CTR_FUNC |= USB_UH1_OC_DIS; /* Over current disable */ if (cpu_is_mx50()) { USBCTRL |= UCTRL_H1PM; /* Host1 Power Mask */ USB_PHY_CTR_FUNC &= ~USB_UH1_OC_DIS; /* Over current enable */ /* Over current polarity low active */ USB_PHY_CTR_FUNC |= USB_UH1_OC_POL; } udelay (1000); if (0 == (0x0C000000 & UH1_PORTSC1)) { printk ("<6>[%s-%d] %s() USB H1 not initialized !!\n",__FILE__,__LINE__,__func__); USBH1_disabled=1; clk_disable(usb_clk); return; } USBH1_disabled=0; /* set UTMI xcvr */ tmp = UH1_PORTSC1 & ~PORTSC_PTS_MASK; tmp |= PORTSC_PTS_UTMI; UH1_PORTSC1 = tmp; /* Set the PHY clock to 24MHz */ USBH1_PHY_CTRL1 &= ~USB_UTMI_PHYCTRL2_PLLDIV_MASK; USBH1_PHY_CTRL1 |= 0x01; // Joseph 20110624 USBH1_PHY_CTRL0 &= ~USB_UTMI_PHYCTRL_CHGRDETON; USBH1_PHY_CTRL0 &= ~USB_UTMI_PHYCTRL_CHGRDETEN; /* Workaround an IC issue for ehci driver: * when turn off root hub port power, EHCI set * PORTSC reserved bits to be 0, but PTW with 0 * means 8 bits tranceiver width, here change * it back to be 16 bits and do PHY diable and * then enable. */ UH1_PORTSC1 |= PORTSC_PTW; /* need to reset the controller here so that the ID pin * is correctly detected. */ /* Stop then Reset */ UH1_USBCMD &= ~UCMD_RUN_STOP; while (UH1_USBCMD & UCMD_RUN_STOP) ; UH1_USBCMD |= UCMD_RESET; while ((UH1_USBCMD) & (UCMD_RESET)) ; /* allow controller to reset, and leave time for * the ULPI transceiver to reset too. */ msleep(100); // MJ: This code appears to prevent the USB port from behaving as a host // port properly. It was #if 1 in the original code, but I have // removed that which has enabled the USB serial adapter to operate #if 0 // force suspend otg port printk ("[%s-%d] %s() \n",__FILE__,__LINE__,__func__); USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_OC_DIS; USBCTRL &= ~UCTRL_OWIE; USB_PHY_CTR_FUNC &= ~0x1000; #endif /* Turn off the usbpll for UTMI tranceivers */ clk_disable(usb_clk); }
static void usbh1_set_utmi_xcvr(void) { u32 tmp; /* Stop then Reset */ UH1_USBCMD &= ~UCMD_RUN_STOP; while (UH1_USBCMD & UCMD_RUN_STOP) ; UH1_USBCMD |= UCMD_RESET; while ((UH1_USBCMD) & (UCMD_RESET)) ; /* For OC and PWR, it is board level setting * The default setting is for mx53 evk */ USBCTRL &= ~UCTRL_H1PM; /* Host1 Power Mask */ USBCTRL &= ~UCTRL_H1WIE; /* Host1 Wakeup Intr Disable */ USB_PHY_CTR_FUNC |= USB_UH1_OC_DIS; /* Over current disable */ if (cpu_is_mx50()) { USBCTRL |= UCTRL_H1PM; /* Host1 Power Mask */ USB_PHY_CTR_FUNC &= ~USB_UH1_OC_DIS; /* Over current enable */ /* Over current polarity low active */ USB_PHY_CTR_FUNC |= USB_UH1_OC_POL; } /* set UTMI xcvr */ tmp = UH1_PORTSC1 & ~PORTSC_PTS_MASK; tmp |= PORTSC_PTS_UTMI; UH1_PORTSC1 = tmp; /* Set the PHY clock to 24MHz */ USBH1_PHY_CTRL1 &= ~USB_UTMI_PHYCTRL2_PLLDIV_MASK; USBH1_PHY_CTRL1 |= 0x01; /* Workaround an IC issue for ehci driver: * when turn off root hub port power, EHCI set * PORTSC reserved bits to be 0, but PTW with 0 * means 8 bits tranceiver width, here change * it back to be 16 bits and do PHY diable and * then enable. */ UH1_PORTSC1 |= PORTSC_PTW; /* need to reset the controller here so that the ID pin * is correctly detected. */ /* Stop then Reset */ UH1_USBCMD &= ~UCMD_RUN_STOP; while (UH1_USBCMD & UCMD_RUN_STOP) ; UH1_USBCMD |= UCMD_RESET; while ((UH1_USBCMD) & (UCMD_RESET)) ; /* allow controller to reset, and leave time for * the ULPI transceiver to reset too. */ msleep(100); /* Turn off the usbpll for UTMI tranceivers */ clk_disable(usb_clk); }
int fsl_usb_host_init(struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; struct fsl_xcvr_ops *xops; pr_debug("%s: pdev=0x%p pdata=0x%p\n", __func__, pdev, pdata); xops = fsl_usb_get_xcvr(pdata->transceiver); if (!xops) { printk(KERN_ERR "%s transceiver ops missing\n", pdata->name); return -EINVAL; } pdata->xcvr_ops = xops; pdata->xcvr_type = xops->xcvr_type; pdata->pdev = pdev; if (fsl_check_usbclk() != 0) return -EINVAL; pr_debug("%s: grab pins\n", __func__); if (pdata->gpio_usb_active && pdata->gpio_usb_active()) return -EINVAL; if (cpu_is_mx50()) /* Turn on AHB CLK for H1*/ USB_CLKONOFF_CTRL &= ~H1_AHBCLK_OFF; /* enable board power supply for xcvr */ if (pdata->xcvr_pwr) { if (pdata->xcvr_pwr->regu1) regulator_enable(pdata->xcvr_pwr->regu1); if (pdata->xcvr_pwr->regu2) regulator_enable(pdata->xcvr_pwr->regu2); } if (xops->init) xops->init(xops); if (usb_register_remote_wakeup(pdev)) pr_debug("%s port is not a wakeup source.\n", pdata->name); if (!(cpu_is_mx6())) { if (xops->xcvr_type == PORTSC_PTS_SERIAL) { if (cpu_is_mx35()) { usbh2_set_serial_xcvr(); /* Close the internal 60Mhz */ USBCTRL &= ~UCTRL_XCSH2; } else if (cpu_is_mx25()) usbh2_set_serial_xcvr(); else usbh1_set_serial_xcvr(); } else if (xops->xcvr_type == PORTSC_PTS_ULPI) { if (!strcmp("Host 1", pdata->name)) usbh1_set_ulpi_xcvr(); if (!strcmp("Host 2", pdata->name)) usbh2_set_ulpi_xcvr(); } else if (xops->xcvr_type == PORTSC_PTS_UTMI) { usbh1_set_utmi_xcvr(); } } else { #ifdef CONFIG_ARCH_MX6 if (!strcmp("Host 1", pdata->name)) { if (machine_is_mx6q_arm2()) USB_H1_CTRL &= ~UCTRL_OVER_CUR_POL; else if (machine_is_mx6q_sabrelite()) USB_H1_CTRL |= UCTRL_OVER_CUR_POL; USB_H1_CTRL |= UCTRL_OVER_CUR_DIS; if (machine_is_cm_fx6()) USB_H1_CTRL |= UCTRL_PWR_POL; } #endif } pr_debug("%s: %s success\n", __func__, pdata->name); return 0; }