/* * make sure USB_CLK is running at 60 MHz +/- 1000 Hz */ static int fsl_check_usbclk(void) { unsigned long freq; usb_ahb_clk = clk_get(NULL, "usb_ahb_clk"); if (clk_enable(usb_ahb_clk)) { if (cpu_is_mx6q() || cpu_is_mx6dl()) return 0; /* there is no ahb clock at mx6 */ printk(KERN_ERR "clk_enable(usb_ahb_clk) failed\n"); return -EINVAL; } clk_put(usb_ahb_clk); usb_clk = clk_get(NULL, "usb_clk"); if (clk_enable(usb_clk)) { if (cpu_is_mx6q() || cpu_is_mx6dl()) return 0; /* there is usb_clk at mx6 */ printk(KERN_ERR "clk_enable(usb_clk) failed\n"); return -EINVAL; } freq = clk_get_rate(usb_clk); clk_put(usb_clk); if ((freq < 59999000) || (freq > 60001000)) { printk(KERN_ERR "USB_CLK=%lu, should be 60MHz\n", freq); return -1; } return 0; }
static int mx6q_seco_q7_fec_phy_reset(struct phy_device *phydev) { int ret; if(cpu_is_mx6q()) mxc_iomux_v3_setup_pad(MX6Q_PAD_RGMII_RX_CTL__GPIO_6_24); if(cpu_is_mx6dl()) mxc_iomux_v3_setup_pad(MX6DL_PAD_RGMII_RX_CTL__GPIO_6_24); ret = gpio_request(MX6_ENET_125MHz_EN, "125mHz_en"); if (!ret) { gpio_direction_output(MX6_ENET_125MHz_EN, 1); gpio_set_value(MX6_ENET_125MHz_EN, 1); printk("Resetting ethernet physical layer.\n"); gpio_set_value(MX6_SECO_Q7_FEC_RESET, 0); msleep(2); gpio_set_value(MX6_SECO_Q7_FEC_RESET, 1); msleep(1); gpio_free(MX6_ENET_125MHz_EN); if(cpu_is_mx6q()) mxc_iomux_v3_setup_pad(MX6Q_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL); if(cpu_is_mx6dl()) mxc_iomux_v3_setup_pad(MX6DL_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL); } else { printk(KERN_ERR "Reset of ethernet physical layer failed.\n"); } return 0; }
static void ov5640_mipi_camera_io_init(void) { struct clk *clko1; if (cpu_is_mx6q()) { mxc_iomux_v3_setup_pad(MX6Q_PAD_CSI0_MCLK__CCM_CLKO); mxc_iomux_v3_setup_pad(MX6Q_PAD_CSI0_DAT18__GPIO_6_4); } else { mxc_iomux_v3_setup_pad(MX6DL_PAD_CSI0_MCLK__CCM_CLKO); mxc_iomux_v3_setup_pad(MX6DL_PAD_CSI0_DAT18__GPIO_6_4); } clko1 = clk_get(NULL, "clko_clk"); if (IS_ERR(clko1)) { pr_err("can't get CLKO1 clock.\n"); } else { long round = clk_round_rate(clko1, 27000000); clk_set_rate(clko1, round); clk_enable(clko1); } /* Camera reset */ gpio_request(MX6_CAMERA_RST, "cam-reset"); gpio_direction_output(MX6_CAMERA_RST, 0); msleep(1); gpio_set_value(MX6_CAMERA_RST, 1); msleep(100); /* for mx6dl, mipi virtual channel 1 connect to csi 0*/ if (cpu_is_mx6dl()) mxc_iomux_set_gpr_register(13, 0, 3, 0); }
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 mx6q_csi0_io_init(void) { if (cpu_is_mx6q()) mxc_iomux_set_gpr_register(1, 19, 1, 1); else if (cpu_is_mx6dl()) mxc_iomux_set_gpr_register(13, 0, 3, 4); }
struct cpu_op *mx6_get_cpu_op(int *op) { if (cpu_is_mx6dl()) { if (arm_max_freq == CPU_AT_1_2GHz) { *op = num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op_1_2G); return mx6dl_cpu_op_1_2G; } else if (arm_max_freq == CPU_AT_1GHz) { *op = num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op_1G); return mx6dl_cpu_op_1G; } else { *op = num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op); return mx6dl_cpu_op; } } else if (cpu_is_mx6q()) { if (arm_max_freq == CPU_AT_1_2GHz) { *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op_1_2G); return mx6q_cpu_op_1_2G; } else if (arm_max_freq == CPU_AT_1GHz) { *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op_1G); return mx6q_cpu_op_1G; } else { *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op); return mx6q_cpu_op; } } else { if (arm_max_freq == CPU_AT_1GHz) { *op = num_cpu_op = ARRAY_SIZE(mx6sl_cpu_op_1G); return mx6sl_cpu_op_1G; } else { *op = num_cpu_op = ARRAY_SIZE(mx6sl_cpu_op); return mx6sl_cpu_op; } } }
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); }
void arch_idle_multi_core(void) { u32 reg; int cpu = smp_processor_id(); #ifdef CONFIG_LOCAL_TIMERS if (!tick_broadcast_oneshot_active() || !tick_oneshot_mode_active()) return; clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); #endif /* iMX6Q and iMX6DL */ if ((cpu_is_mx6q() && chip_rev >= IMX_CHIP_REVISION_1_2) || (cpu_is_mx6dl() && chip_rev >= IMX_CHIP_REVISION_1_1)) { /* * This code should only be executed on MX6QTO1.2 or later * and MX6DL TO1.1 or later. * These chips have the HW fix for the WAIT mode issue. * Ensure that the CGPR bit 17 is set to enable the fix. */ reg = __raw_readl(MXC_CCM_CGPR); reg |= MXC_CCM_CGPR_WAIT_MODE_FIX; __raw_writel(reg, MXC_CCM_CGPR); ca9_do_idle(); } else arch_idle_with_workaround(cpu); #ifdef CONFIG_LOCAL_TIMERS clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); #endif }
static int __init busfreq_init(void) { if (platform_driver_register(&busfreq_driver) != 0) { printk(KERN_ERR "busfreq_driver register failed\n"); return -ENODEV; } printk(KERN_INFO "Bus freq driver module loaded\n"); #ifdef CONFIG_MX6_VPU_352M if (cpu_is_mx6q()) bus_freq_scaling_is_active = 0;/*disable bus_freq*/ #else /* Enable busfreq by default. */ bus_freq_scaling_is_active = 1; #endif if (cpu_is_mx6q()) set_high_bus_freq(1); else if (cpu_is_mx6dl()) set_high_bus_freq(0); printk(KERN_INFO "Bus freq driver Enabled\n"); return 0; }
static int plt_sd_pad_change(unsigned int index, int clock) { /* LOW speed is the default state of SD pads */ static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED; iomux_v3_cfg_t *sd_pads_200mhz = NULL; iomux_v3_cfg_t *sd_pads_100mhz = NULL; iomux_v3_cfg_t *sd_pads_50mhz = NULL; u32 sd_pads_200mhz_cnt; u32 sd_pads_100mhz_cnt; u32 sd_pads_50mhz_cnt; if (index != 2) { printk(KERN_ERR"no such SD host controller index %d\n", index); return -EINVAL; } if (cpu_is_mx6q()) { sd_pads_200mhz = mx6q_sd3_200mhz; sd_pads_100mhz = mx6q_sd3_100mhz; sd_pads_50mhz = mx6q_sd3_50mhz; sd_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd3_200mhz); sd_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd3_100mhz); sd_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd3_50mhz); } else if (cpu_is_mx6dl()) { sd_pads_200mhz = mx6dl_sd3_200mhz; sd_pads_100mhz = mx6dl_sd3_100mhz; sd_pads_50mhz = mx6dl_sd3_50mhz; sd_pads_200mhz_cnt = ARRAY_SIZE(mx6dl_sd3_200mhz); sd_pads_100mhz_cnt = ARRAY_SIZE(mx6dl_sd3_100mhz); sd_pads_50mhz_cnt = ARRAY_SIZE(mx6dl_sd3_50mhz); } if (clock > 100000000) { if (pad_mode == SD_PAD_MODE_HIGH_SPEED) return 0; BUG_ON(!sd_pads_200mhz); pad_mode = SD_PAD_MODE_HIGH_SPEED; return mxc_iomux_v3_setup_multiple_pads(sd_pads_200mhz, sd_pads_200mhz_cnt); } else if (clock > 52000000) { if (pad_mode == SD_PAD_MODE_MED_SPEED) return 0; BUG_ON(!sd_pads_100mhz); pad_mode = SD_PAD_MODE_MED_SPEED; return mxc_iomux_v3_setup_multiple_pads(sd_pads_100mhz, sd_pads_100mhz_cnt); } else { if (pad_mode == SD_PAD_MODE_LOW_SPEED) return 0; BUG_ON(!sd_pads_50mhz); pad_mode = SD_PAD_MODE_LOW_SPEED; return mxc_iomux_v3_setup_multiple_pads(sd_pads_50mhz, sd_pads_50mhz_cnt); } }
static void hdmi_disable_ddc_pin(void) { if (cpu_is_mx6dl()) mxc_iomux_v3_setup_multiple_pads(mx6dl_sabreauto_i2c2_pads, ARRAY_SIZE(mx6dl_sabreauto_i2c2_pads)); else mxc_iomux_v3_setup_multiple_pads(mx6q_sabreauto_i2c2_pads, ARRAY_SIZE(mx6q_sabreauto_i2c2_pads)); }
static void hdmi_enable_ddc_pin(void) { if (cpu_is_mx6dl()) mxc_iomux_v3_setup_multiple_pads(mx6dl_hdmidongle_hdmi_ddc_pads, ARRAY_SIZE(mx6dl_hdmidongle_hdmi_ddc_pads)); else mxc_iomux_v3_setup_multiple_pads(mx6q_hdmidongle_hdmi_ddc_pads, ARRAY_SIZE(mx6q_hdmidongle_hdmi_ddc_pads)); }
static void mipi_camera_io_init(void) { pr_info("%s\n", __func__); camera_reset(GP_CAMERA_RESET); /* for mx6dl, mipi virtual channel 1 connect to csi 1*/ if (cpu_is_mx6dl()) mxc_iomux_set_gpr_register(13, 3, 3, 1); }
/* * Returns: * the silicon revision of the cpu */ int mx6dl_revision(void) { if (!cpu_is_mx6dl()) return -EINVAL; if (cpu_silicon_rev == -1) cpu_silicon_rev = mx6_get_srev(); return cpu_silicon_rev; }
static void imx6_add_video_clks(void __iomem *anab, void __iomem *cb) { clks[IMX6QDL_CLK_PLL5_POST_DIV] = imx_clk_divider_table("pll5_post_div", "pll5_video", anab + 0xa0, 19, 2, post_div_table); clks[IMX6QDL_CLK_PLL5_VIDEO_DIV] = imx_clk_divider_table("pll5_video_div", "pll5_post_div", anab + 0x170, 30, 2, video_div_table); clks[IMX6QDL_CLK_IPU1_SEL] = imx_clk_mux("ipu1_sel", cb + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); clks[IMX6QDL_CLK_IPU2_SEL] = imx_clk_mux("ipu2_sel", cb + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); clks[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_mux_p("ldb_di0_sel", cb + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); clks[IMX6QDL_CLK_LDB_DI1_SEL] = imx_clk_mux_p("ldb_di1_sel", cb + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); clks[IMX6QDL_CLK_IPU1_DI0_PRE_SEL] = imx_clk_mux_p("ipu1_di0_pre_sel", cb + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); clks[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_mux_p("ipu1_di1_pre_sel", cb + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); clks[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_mux_p("ipu2_di0_pre_sel", cb + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); clks[IMX6QDL_CLK_IPU2_DI1_PRE_SEL] = imx_clk_mux_p("ipu2_di1_pre_sel", cb + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); clks[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_p("ipu1_di0_sel", cb + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels)); clks[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_p("ipu1_di1_sel", cb + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels)); clks[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_p("ipu2_di0_sel", cb + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels)); clks[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_p("ipu2_di1_sel", cb + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels)); clks[IMX6QDL_CLK_IPU1_PODF] = imx_clk_divider("ipu1_podf", "ipu1_sel", cb + 0x3c, 11, 3); clks[IMX6QDL_CLK_IPU2_PODF] = imx_clk_divider("ipu2_podf", "ipu2_sel", cb + 0x3c, 16, 3); clks[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); clks[IMX6QDL_CLK_LDB_DI0_PODF] = imx_clk_divider_np("ldb_di0_podf", "ldb_di0_div_3_5", cb + 0x20, 10, 1); clks[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); clks[IMX6QDL_CLK_LDB_DI1_PODF] = imx_clk_divider_np("ldb_di1_podf", "ldb_di1_div_3_5", cb + 0x20, 11, 1); clks[IMX6QDL_CLK_IPU1_DI0_PRE] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", cb + 0x34, 3, 3); clks[IMX6QDL_CLK_IPU1_DI1_PRE] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", cb + 0x34, 12, 3); clks[IMX6QDL_CLK_IPU2_DI0_PRE] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", cb + 0x38, 3, 3); clks[IMX6QDL_CLK_IPU2_DI1_PRE] = imx_clk_divider("ipu2_di1_pre", "ipu2_di1_pre_sel", cb + 0x38, 12, 3); clks[IMX6QDL_CLK_IPU1] = imx_clk_gate2("ipu1", "ipu1_podf", cb + 0x74, 0); clks[IMX6QDL_CLK_IPU1_DI0] = imx_clk_gate2("ipu1_di0", "ipu1_di0_sel", cb + 0x74, 2); clks[IMX6QDL_CLK_IPU1_DI1] = imx_clk_gate2("ipu1_di1", "ipu1_di1_sel", cb + 0x74, 4); clks[IMX6QDL_CLK_IPU2] = imx_clk_gate2("ipu2", "ipu2_podf", cb + 0x74, 6); clks[IMX6QDL_CLK_IPU2_DI0] = imx_clk_gate2("ipu2_di0", "ipu2_di0_sel", cb + 0x74, 8); clks[IMX6QDL_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", cb + 0x74, 12); clks[IMX6QDL_CLK_LDB_DI1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", cb + 0x74, 14); clks[IMX6QDL_CLK_IPU2_DI1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", cb + 0x74, 10); clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI0_SEL], clks[IMX6QDL_CLK_IPU1_DI0_PRE]); clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI1_SEL], clks[IMX6QDL_CLK_IPU1_DI1_PRE]); clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI0_SEL], clks[IMX6QDL_CLK_IPU2_DI0_PRE]); clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI1_SEL], clks[IMX6QDL_CLK_IPU2_DI1_PRE]); clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI0_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]); clk_set_parent(clks[IMX6QDL_CLK_IPU1_DI1_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]); clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI0_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]); clk_set_parent(clks[IMX6QDL_CLK_IPU2_DI1_PRE_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]); if ((imx_silicon_revision() != IMX_CHIP_REV_1_0) || cpu_is_mx6dl()) { clk_set_parent(clks[IMX6QDL_CLK_LDB_DI0_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]); clk_set_parent(clks[IMX6QDL_CLK_LDB_DI1_SEL], clks[IMX6QDL_CLK_PLL5_VIDEO_DIV]); } }
static void hsic_start(void) { pr_debug("%s", __func__); /* strobe 47K pull up */ if (cpu_is_mx6q()) mxc_iomux_v3_setup_pad( MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE_START); else if (cpu_is_mx6dl()) mxc_iomux_v3_setup_pad( MX6DL_PAD_RGMII_RXC__USBOH3_H3_STROBE_START); }
static int plt_sd3_pad_change(int clock) { static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED; if (clock > 100000000) { if (pad_mode == SD_PAD_MODE_HIGH_SPEED) return 0; pad_mode = SD_PAD_MODE_HIGH_SPEED; if (cpu_is_mx6q()) { return mxc_iomux_v3_setup_multiple_pads(mx6q_sd3_200mhz, ARRAY_SIZE(mx6dl_sd3_200mhz)); } else if (cpu_is_mx6dl()) { return mxc_iomux_v3_setup_multiple_pads(mx6dl_sd3_200mhz, ARRAY_SIZE(mx6dl_sd3_200mhz)); } } else if (clock > 52000000) { if (pad_mode == SD_PAD_MODE_MED_SPEED) return 0; pad_mode = SD_PAD_MODE_MED_SPEED; if (cpu_is_mx6q()) { return mxc_iomux_v3_setup_multiple_pads(mx6q_sd3_100mhz, ARRAY_SIZE(mx6dl_sd3_200mhz)); } else if (cpu_is_mx6dl()) { return mxc_iomux_v3_setup_multiple_pads(mx6dl_sd3_100mhz, ARRAY_SIZE(mx6dl_sd3_200mhz)); } } else { if (pad_mode == SD_PAD_MODE_LOW_SPEED) return 0; pad_mode = SD_PAD_MODE_LOW_SPEED; if (cpu_is_mx6q()) { return mxc_iomux_v3_setup_multiple_pads(mx6q_sd3_50mhz, ARRAY_SIZE(mx6dl_sd3_200mhz)); } else if (cpu_is_mx6dl()) { return mxc_iomux_v3_setup_multiple_pads(mx6dl_sd3_50mhz, ARRAY_SIZE(mx6dl_sd3_200mhz)); } } }
/*! * This is the probe routine for the bus frequency driver. * * @param pdev The platform device structure * * @return The function returns 0 on success * */ static int __devinit busfreq_probe(struct platform_device *pdev) { u32 err; busfreq_dev = &pdev->dev; pll2_400 = clk_get(NULL, "pll2_pfd_400M"); if (IS_ERR(pll2_400)) { printk(KERN_DEBUG "%s: failed to get axi_clk\n", __func__); return PTR_ERR(pll2_400); } cpu_clk = clk_get(NULL, "cpu_clk"); if (IS_ERR(cpu_clk)) { printk(KERN_DEBUG "%s: failed to get cpu_clk\n", __func__); return PTR_ERR(cpu_clk); } pll3 = clk_get(NULL, "pll3_main_clk"); err = sysfs_create_file(&busfreq_dev->kobj, &dev_attr_enable.attr); if (err) { printk(KERN_ERR "Unable to register sysdev entry for BUSFREQ"); return err; } cpu_op_tbl = get_cpu_op(&cpu_op_nr); low_bus_freq_mode = 0; high_bus_freq_mode = 1; med_bus_freq_mode = 0; bus_freq_scaling_is_active = 0; bus_freq_scaling_initialized = 1; if (cpu_is_mx6q()) { ddr_low_rate = LPAPM_CLK; ddr_med_rate = DDR_MED_CLK; ddr_normal_rate = DDR3_NORMAL_CLK; } if (cpu_is_mx6dl()) { ddr_low_rate = LPAPM_CLK; ddr_normal_rate = ddr_med_rate = DDR_MED_CLK; } INIT_DELAYED_WORK(&low_bus_freq_handler, reduce_bus_freq_handler); mutex_init(&bus_freq_mutex); return 0; }
static int __init gpmi_nand_platform_init(void) { iomux_v3_cfg_t *nand_pads = NULL; u32 nand_pads_cnt; if (cpu_is_mx6q()) { nand_pads = mx6q_gpmi_nand; nand_pads_cnt = ARRAY_SIZE(mx6q_gpmi_nand); } else if (cpu_is_mx6dl()) { nand_pads = mx6dl_gpmi_nand; nand_pads_cnt = ARRAY_SIZE(mx6dl_gpmi_nand); } BUG_ON(!nand_pads); return mxc_iomux_v3_setup_multiple_pads(nand_pads, nand_pads_cnt); }
static inline void __init mx6q_csi0_io_init(void) { /* Camera reset */ gpio_request(SABREAUTO_CSI0_RST, "cam-reset"); gpio_direction_output(SABREAUTO_CSI0_RST, 1); /* Camera power down */ gpio_request(SABREAUTO_CSI0_PWN, "cam-pwdn"); gpio_direction_output(SABREAUTO_CSI0_PWN, 1); msleep(1); gpio_set_value(SABREAUTO_CSI0_PWN, 0); if (cpu_is_mx6q()) mxc_iomux_set_gpr_register(1, 19, 1, 1); else if (cpu_is_mx6dl()) mxc_iomux_set_gpr_register(13, 0, 3, 4); }
static ssize_t I2C_enable_write(struct file *filp, const char *buff, size_t len, loff_t *off) { char bbuf[128]; int retlen; retlen=copy_from_user(bbuf,buff,len); bbuf[len]=0; printk("\n I2C_enable write -- Str=%s\n",bbuf); static iomux_v3_cfg_t mx6q_I2C_pads[] = {MX6Q_PAD_GPIO_3__GPIO_1_3, MX6Q_PAD_GPIO_6__GPIO_1_6, MX6Q_PAD_NANDF_ALE__GPIO_6_8, MX6Q_PAD_NANDF_CS3__GPIO_6_16}; static iomux_v3_cfg_t mx6dl_I2C_pads[] = {MX6DL_PAD_GPIO_3__GPIO_1_3, MX6DL_PAD_GPIO_6__GPIO_1_6, MX6DL_PAD_NANDF_ALE__GPIO_6_8, MX6DL_PAD_NANDF_CS3__GPIO_6_16}; if(strtoint(bbuf)) { printk("set I2C Enable.\n"); if (cpu_is_mx6q()) mxc_iomux_v3_setup_multiple_pads(mx6q_I2C_pads, ARRAY_SIZE(mx6q_I2C_pads)); else if (cpu_is_mx6dl()) mxc_iomux_v3_setup_multiple_pads(mx6dl_I2C_pads, ARRAY_SIZE(mx6dl_I2C_pads)); gpio_request(I2C_SCL_ENABLE, "I2CSCL"); //willy add gpio_direction_input(I2C_SCL_ENABLE); gpio_export(I2C_SCL_ENABLE,0); gpio_request(I2C_SDA_ENABLE, "I2CSDA"); //willy add gpio_direction_output(I2C_SDA_ENABLE, 0); gpio_export(I2C_SDA_ENABLE,0); gpio_request(I2C_IRQ_ENABLE, "I2CIRQ"); //willy add gpio_direction_input(I2C_IRQ_ENABLE); gpio_export(I2C_IRQ_ENABLE,0); gpio_request(I2C_RST_ENABLE, "I2CRST"); //willy add gpio_direction_output(I2C_RST_ENABLE, 0); gpio_export(I2C_RST_ENABLE,0); // sys_chmod("/sys/class/gpio/gpio3/value", 420); // sys_chmod("/sys/class/gpio/gpio6/value", 420); // sys_chmod("/sys/class/gpio/gpio168/value", 420); // sys_chmod("/sys/class/gpio/gpio176/value", 420); } else { } return len; }
struct cpu_op *mx6_get_cpu_op(int *op) { if (cpu_is_mx6dl()) { if (arm_max_freq == CPU_AT_1_2GHz) { *op = num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op_1_2G); return mx6dl_cpu_op_1_2G; } else if (arm_max_freq == CPU_AT_1GHz) { *op = num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op_1G); return mx6dl_cpu_op_1G; } else { *op = num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op); return mx6dl_cpu_op; } } else if (cpu_is_mx6q()) { if (arm_max_freq == CPU_AT_1_2GHz) { *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op_1_2G); return mx6q_cpu_op_1_2G; } else if (arm_max_freq == CPU_AT_1GHz) { *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op_1G); return mx6q_cpu_op_1G; } else { *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op); return mx6q_cpu_op; } } else { if (arm_max_freq == CPU_AT_1GHz) { *op = num_cpu_op = ARRAY_SIZE(mx6sl_cpu_op_1G); #ifdef CONFIG_LAB126 if(lab126_board_is(BOARD_ID_BOURBON_WFO) || lab126_board_is(BOARD_ID_WARIO_4_256M_CFG_C) || lab126_board_is(BOARD_ID_BOURBON_WFO_PREEVT2)) { return mx6sl_cpu_op_1G_Bourbon; } else #endif { return mx6sl_cpu_op_1G; } } else { *op = num_cpu_op = ARRAY_SIZE(mx6sl_cpu_op); return mx6sl_cpu_op; } } }
/* * set_mclk_rate * * @param p_mclk_freq mclk frequence * @param csi csi 0 or csi 1 * */ void set_mclk_rate(uint32_t *p_mclk_freq, uint32_t csi) { struct clk *clk; uint32_t freq = 0; char *mclk; if (cpu_is_mx53()) { if (csi == 0) mclk = "ssi_ext1_clk"; else { pr_err("invalid csi num %d\n", csi); return; } } else if (cpu_is_mx6q() || cpu_is_mx6dl()) { if (csi == 0) { mclk = "clko2_clk"; } else { pr_err("invalid csi num %d\n", csi); return; }; } else if (cpu_is_mx25() || cpu_is_mx6sl()) { /* only has CSI0 */ mclk = "csi_clk"; } else { if (csi == 0) { mclk = "csi_mclk1"; } else if (csi == 1) { mclk = "csi_mclk2"; } else { pr_err("invalid csi num %d\n", csi); return; } } clk = clk_get(NULL, mclk); freq = clk_round_rate(clk, *p_mclk_freq); clk_set_rate(clk, freq); *p_mclk_freq = freq; clk_put(clk); pr_debug("%s frequency = %d\n", mclk, *p_mclk_freq); }
static void ov5640_mipi_camera_io_init(void) { IOMUX_SETUP(mipi_pads); pr_info("%s\n", __func__); mipi_pwm = pwm_request(2, "mipi_clock"); if (IS_ERR(mipi_pwm)) { pr_err("unable to request PWM for mipi_clock\n"); } else { unsigned period = 1000/22; pr_info("got pwm for mipi_clock\n"); pwm_config(mipi_pwm, period >> 1, period); pwm_enable(mipi_pwm); } camera_reset(IMX_GPIO_NR(6, 9), 1, IMX_GPIO_NR(2, 5), IMX_GPIO_NR(6, 11)); /* for mx6dl, mipi virtual channel 1 connect to csi 1*/ if (cpu_is_mx6dl()) mxc_iomux_set_gpr_register(13, 3, 3, 1); }
void arch_idle_multi_core(int cpu) { u32 reg; /* iMX6Q and iMX6DL */ if ((cpu_is_mx6q() && chip_rev >= IMX_CHIP_REVISION_1_2) || (cpu_is_mx6dl() && chip_rev >= IMX_CHIP_REVISION_1_1)) { /* * This code should only be executed on MX6QTO1.2 or later * and MX6DL TO1.1 or later. * These chips have the HW fix for the WAIT mode issue. * Ensure that the CGPR bit 17 is set to enable the fix. */ reg = __raw_readl(MXC_CCM_CGPR); reg |= MXC_CCM_CGPR_WAIT_MODE_FIX; __raw_writel(reg, MXC_CCM_CGPR); ca9_do_idle(); } else arch_idle_with_workaround(cpu); }
static void phyflex_err006282_workaround(void) { /* * Boards beginning with 1362.2 have the SD4_DAT3 pin connected * to the CMIC. If this pin isn't toggled within 10s the boards * reset. The pin is unconnected on older boards, so we do not * need a check for older boards before applying this fixup. */ gpio_direction_output(MX6_PHYFLEX_ERR006282, 0); mdelay(2); gpio_direction_output(MX6_PHYFLEX_ERR006282, 1); mdelay(2); gpio_set_value(MX6_PHYFLEX_ERR006282, 0); if (cpu_is_mx6q()) mxc_iomux_v3_setup_pad(MX6Q_PAD_SD4_DAT3__GPIO_2_11_PD); else if (cpu_is_mx6dl()) mxc_iomux_v3_setup_pad(MX6DL_PAD_SD4_DAT3__GPIO_2_11); gpio_direction_input(MX6_PHYFLEX_ERR006282); }
static int ldb_disp_init(struct mxc_dispdrv_handle *disp, struct mxc_dispdrv_setting *setting) { int ret = 0, i; struct ldb_data *ldb = mxc_dispdrv_getdata(disp); struct fsl_mxc_ldb_platform_data *plat_data = ldb->pdev->dev.platform_data; struct resource *res; uint32_t base_addr; uint32_t reg, setting_idx; uint32_t ch_mask = 0, ch_val = 0; uint32_t ipu_id, disp_id; /* if input format not valid, make RGB666 as default*/ if (!valid_mode(setting->if_fmt)) { dev_warn(&ldb->pdev->dev, "Input pixel format not valid" " use default RGB666\n"); setting->if_fmt = IPU_PIX_FMT_RGB666; } if (!ldb->inited) { char di_clk[] = "ipu1_di0_clk"; char ldb_clk[] = "ldb_di0_clk"; int lvds_channel = 0; setting_idx = 0; res = platform_get_resource(ldb->pdev, IORESOURCE_MEM, 0); if (IS_ERR(res)) return -ENOMEM; base_addr = res->start; ldb->reg = ioremap(base_addr, res->end - res->start + 1); ldb->control_reg = ldb->reg + 2; ldb->gpr3_reg = ldb->reg + 3; ldb->lvds_bg_reg = regulator_get(&ldb->pdev->dev, plat_data->lvds_bg_reg); if (!IS_ERR(ldb->lvds_bg_reg)) { regulator_set_voltage(ldb->lvds_bg_reg, 2500000, 2500000); regulator_enable(ldb->lvds_bg_reg); } /* ipu selected by platform data setting */ setting->dev_id = plat_data->ipu_id; reg = readl(ldb->control_reg); /* refrence resistor select */ reg &= ~LDB_BGREF_RMODE_MASK; if (plat_data->ext_ref) reg |= LDB_BGREF_RMODE_EXT; else reg |= LDB_BGREF_RMODE_INT; /* TODO: now only use SPWG data mapping for both channel */ reg &= ~(LDB_BIT_MAP_CH0_MASK | LDB_BIT_MAP_CH1_MASK); reg |= LDB_BIT_MAP_CH0_SPWG | LDB_BIT_MAP_CH1_SPWG; /* channel mode setting */ reg &= ~(LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK); reg &= ~(LDB_DATA_WIDTH_CH0_MASK | LDB_DATA_WIDTH_CH1_MASK); if (bits_per_pixel(setting->if_fmt) == 24) reg |= LDB_DATA_WIDTH_CH0_24 | LDB_DATA_WIDTH_CH1_24; else reg |= LDB_DATA_WIDTH_CH0_18 | LDB_DATA_WIDTH_CH1_18; if (g_ldb_mode) ldb->mode = g_ldb_mode; else ldb->mode = plat_data->mode; if ((ldb->mode == LDB_SIN0) || (ldb->mode == LDB_SIN1)) { ret = ldb->mode - LDB_SIN0; if (plat_data->disp_id != ret) { dev_warn(&ldb->pdev->dev, "change IPU DI%d to IPU DI%d for LDB " "channel%d.\n", plat_data->disp_id, ret, ret); plat_data->disp_id = ret; } } else if (((ldb->mode == LDB_SEP0) || (ldb->mode == LDB_SEP1)) && (cpu_is_mx6q() || cpu_is_mx6dl())) { if (plat_data->disp_id == plat_data->sec_disp_id) { dev_err(&ldb->pdev->dev, "For LVDS separate mode," "two DIs should be different!\n"); return -EINVAL; } if (((!plat_data->disp_id) && (ldb->mode == LDB_SEP1)) || ((plat_data->disp_id) && (ldb->mode == LDB_SEP0))) { dev_dbg(&ldb->pdev->dev, "LVDS separate mode:" "swap DI configuration!\n"); ipu_id = plat_data->ipu_id; disp_id = plat_data->disp_id; plat_data->ipu_id = plat_data->sec_ipu_id; plat_data->disp_id = plat_data->sec_disp_id; plat_data->sec_ipu_id = ipu_id; plat_data->sec_disp_id = disp_id; } } if (ldb->mode == LDB_SPL_DI0) { reg |= LDB_SPLIT_MODE_EN | LDB_CH0_MODE_EN_TO_DI0 | LDB_CH1_MODE_EN_TO_DI0; setting->disp_id = 0; } else if (ldb->mode == LDB_SPL_DI1) { reg |= LDB_SPLIT_MODE_EN | LDB_CH0_MODE_EN_TO_DI1 | LDB_CH1_MODE_EN_TO_DI1; setting->disp_id = 1; } else if (ldb->mode == LDB_DUL_DI0) { reg &= ~LDB_SPLIT_MODE_EN; reg |= LDB_CH0_MODE_EN_TO_DI0 | LDB_CH1_MODE_EN_TO_DI0; setting->disp_id = 0; } else if (ldb->mode == LDB_DUL_DI1) { reg &= ~LDB_SPLIT_MODE_EN; reg |= LDB_CH0_MODE_EN_TO_DI1 | LDB_CH1_MODE_EN_TO_DI1; setting->disp_id = 1; } else if (ldb->mode == LDB_SIN0) { reg &= ~LDB_SPLIT_MODE_EN; setting->disp_id = plat_data->disp_id; if (setting->disp_id == 0) reg |= LDB_CH0_MODE_EN_TO_DI0; else reg |= LDB_CH0_MODE_EN_TO_DI1; ch_mask = LDB_CH0_MODE_MASK; ch_val = reg & LDB_CH0_MODE_MASK; } else if (ldb->mode == LDB_SIN1) { reg &= ~LDB_SPLIT_MODE_EN; setting->disp_id = plat_data->disp_id; if (setting->disp_id == 0) reg |= LDB_CH1_MODE_EN_TO_DI0; else reg |= LDB_CH1_MODE_EN_TO_DI1; ch_mask = LDB_CH1_MODE_MASK; ch_val = reg & LDB_CH1_MODE_MASK; } else { /* separate mode*/ setting->disp_id = plat_data->disp_id; /* first output is LVDS0 or LVDS1 */ if (ldb->mode == LDB_SEP0) lvds_channel = 0; else lvds_channel = 1; reg &= ~LDB_SPLIT_MODE_EN; if ((lvds_channel == 0) && (setting->disp_id == 0)) reg |= LDB_CH0_MODE_EN_TO_DI0; else if ((lvds_channel == 0) && (setting->disp_id == 1)) reg |= LDB_CH0_MODE_EN_TO_DI1; else if ((lvds_channel == 1) && (setting->disp_id == 0)) reg |= LDB_CH1_MODE_EN_TO_DI0; else reg |= LDB_CH1_MODE_EN_TO_DI1; ch_mask = lvds_channel ? LDB_CH1_MODE_MASK : LDB_CH0_MODE_MASK; ch_val = reg & ch_mask; if (bits_per_pixel(setting->if_fmt) == 24) { if (lvds_channel == 0) reg &= ~LDB_DATA_WIDTH_CH1_24; else reg &= ~LDB_DATA_WIDTH_CH0_24; } else { if (lvds_channel == 0) reg &= ~LDB_DATA_WIDTH_CH1_18; else reg &= ~LDB_DATA_WIDTH_CH0_18; } } writel(reg, ldb->control_reg); if (ldb->mode < LDB_SIN0) { ch_mask = LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK; ch_val = reg & (LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK); } /* clock setting */ if ((cpu_is_mx6q() || cpu_is_mx6dl()) && ((ldb->mode == LDB_SEP0) || (ldb->mode == LDB_SEP1))) ldb_clk[6] += lvds_channel; else ldb_clk[6] += setting->disp_id; ldb->setting[setting_idx].ldb_di_clk = clk_get(&ldb->pdev->dev, ldb_clk); if (IS_ERR(ldb->setting[setting_idx].ldb_di_clk)) { dev_err(&ldb->pdev->dev, "get ldb clk0 failed\n"); iounmap(ldb->reg); return PTR_ERR(ldb->setting[setting_idx].ldb_di_clk); } di_clk[3] += setting->dev_id; di_clk[7] += setting->disp_id; ldb->setting[setting_idx].di_clk = clk_get(&ldb->pdev->dev, di_clk); if (IS_ERR(ldb->setting[setting_idx].di_clk)) { dev_err(&ldb->pdev->dev, "get di clk0 failed\n"); iounmap(ldb->reg); return PTR_ERR(ldb->setting[setting_idx].di_clk); } dev_dbg(&ldb->pdev->dev, "ldb_clk to di clk: %s -> %s\n", ldb_clk, di_clk); /* fb notifier for clk setting */ ldb->nb.notifier_call = ldb_fb_event, ret = fb_register_client(&ldb->nb); if (ret < 0) { iounmap(ldb->reg); return ret; } ldb->inited = true; } else { /* second time for separate mode */ char di_clk[] = "ipu1_di0_clk"; char ldb_clk[] = "ldb_di0_clk"; int lvds_channel; if ((ldb->mode == LDB_SPL_DI0) || (ldb->mode == LDB_SPL_DI1) || (ldb->mode == LDB_DUL_DI0) || (ldb->mode == LDB_DUL_DI1) || (ldb->mode == LDB_SIN0) || (ldb->mode == LDB_SIN1)) { dev_err(&ldb->pdev->dev, "for second ldb disp" "ldb mode should in separate mode\n"); return -EINVAL; } setting_idx = 1; if (cpu_is_mx6q() || cpu_is_mx6dl()) { setting->dev_id = plat_data->sec_ipu_id; setting->disp_id = plat_data->sec_disp_id; } else { setting->dev_id = plat_data->ipu_id; setting->disp_id = !plat_data->disp_id; } if (setting->disp_id == ldb->setting[0].di) { dev_err(&ldb->pdev->dev, "Err: for second ldb disp in" "separate mode, DI should be different!\n"); return -EINVAL; } /* second output is LVDS0 or LVDS1 */ if (ldb->mode == LDB_SEP0) lvds_channel = 1; else lvds_channel = 0; reg = readl(ldb->control_reg); if ((lvds_channel == 0) && (setting->disp_id == 0)) reg |= LDB_CH0_MODE_EN_TO_DI0; else if ((lvds_channel == 0) && (setting->disp_id == 1)) reg |= LDB_CH0_MODE_EN_TO_DI1; else if ((lvds_channel == 1) && (setting->disp_id == 0)) reg |= LDB_CH1_MODE_EN_TO_DI0; else reg |= LDB_CH1_MODE_EN_TO_DI1; ch_mask = lvds_channel ? LDB_CH1_MODE_MASK : LDB_CH0_MODE_MASK; ch_val = reg & ch_mask; if (bits_per_pixel(setting->if_fmt) == 24) { if (lvds_channel == 0) reg |= LDB_DATA_WIDTH_CH0_24; else reg |= LDB_DATA_WIDTH_CH1_24; } else { if (lvds_channel == 0) reg |= LDB_DATA_WIDTH_CH0_18; else reg |= LDB_DATA_WIDTH_CH1_18; } writel(reg, ldb->control_reg); /* clock setting */ if (cpu_is_mx6q() || cpu_is_mx6dl()) ldb_clk[6] += lvds_channel; else ldb_clk[6] += setting->disp_id; ldb->setting[setting_idx].ldb_di_clk = clk_get(&ldb->pdev->dev, ldb_clk); if (IS_ERR(ldb->setting[setting_idx].ldb_di_clk)) { dev_err(&ldb->pdev->dev, "get ldb clk1 failed\n"); return PTR_ERR(ldb->setting[setting_idx].ldb_di_clk); } di_clk[3] += setting->dev_id; di_clk[7] += setting->disp_id; ldb->setting[setting_idx].di_clk = clk_get(&ldb->pdev->dev, di_clk); if (IS_ERR(ldb->setting[setting_idx].di_clk)) { dev_err(&ldb->pdev->dev, "get di clk1 failed\n"); return PTR_ERR(ldb->setting[setting_idx].di_clk); } dev_dbg(&ldb->pdev->dev, "ldb_clk to di clk: %s -> %s\n", ldb_clk, di_clk); } ldb->setting[setting_idx].ch_mask = ch_mask; ldb->setting[setting_idx].ch_val = ch_val; if (cpu_is_mx6q() || cpu_is_mx6dl()) ldb_ipu_ldb_route(setting->dev_id, setting->disp_id, ldb); /* * ldb_di0_clk -> ipux_di0_clk * ldb_di1_clk -> ipux_di1_clk */ clk_set_parent(ldb->setting[setting_idx].di_clk, ldb->setting[setting_idx].ldb_di_clk); /* must use spec video mode defined by driver */ ret = fb_find_mode(&setting->fbi->var, setting->fbi, setting->dft_mode_str, ldb_modedb, ldb_modedb_sz, NULL, setting->default_bpp); if (ret != 1) fb_videomode_to_var(&setting->fbi->var, &ldb_modedb[0]); INIT_LIST_HEAD(&setting->fbi->modelist); for (i = 0; i < ldb_modedb_sz; i++) { struct fb_videomode m; fb_var_to_videomode(&m, &setting->fbi->var); if (fb_mode_is_equal(&m, &ldb_modedb[i])) { fb_add_videomode(&ldb_modedb[i], &setting->fbi->modelist); break; } } /* save current ldb setting for fb notifier */ ldb->setting[setting_idx].active = true; ldb->setting[setting_idx].ipu = setting->dev_id; ldb->setting[setting_idx].di = setting->disp_id; return ret; }
static int mx6_suspend_enter(suspend_state_t state) { unsigned int wake_irq_isr[4]; unsigned int cpu_type; struct gic_dist_state gds; struct gic_cpu_state gcs; bool arm_pg = false; if (cpu_is_mx6q()) cpu_type = MXC_CPU_MX6Q; else if (cpu_is_mx6dl()) cpu_type = MXC_CPU_MX6DL; else cpu_type = MXC_CPU_MX6SL; wake_irq_isr[0] = __raw_readl(gpc_base + GPC_ISR1_OFFSET) & gpc_wake_irq[0]; wake_irq_isr[1] = __raw_readl(gpc_base + GPC_ISR2_OFFSET) & gpc_wake_irq[1]; wake_irq_isr[2] = __raw_readl(gpc_base + GPC_ISR3_OFFSET) & gpc_wake_irq[2]; wake_irq_isr[3] = __raw_readl(gpc_base + GPC_ISR4_OFFSET) & gpc_wake_irq[3]; if (wake_irq_isr[0] | wake_irq_isr[1] | wake_irq_isr[2] | wake_irq_isr[3]) { printk(KERN_INFO "There are wakeup irq pending,system resume!\n"); printk(KERN_INFO "wake_irq_isr[0-3]: 0x%x, 0x%x, 0x%x, 0x%x\n", wake_irq_isr[0], wake_irq_isr[1], wake_irq_isr[2], wake_irq_isr[3]); return 0; } mx6_suspend_store(); /* * i.MX6dl TO1.0/i.MX6dq TO1.1/1.0 TKT094231: can't support * ARM_POWER_OFF mode. */ if (state == PM_SUSPEND_MEM && ((mx6dl_revision() == IMX_CHIP_REVISION_1_0) || (cpu_is_mx6q() && mx6q_revision() <= IMX_CHIP_REVISION_1_1))) { state = PM_SUSPEND_STANDBY; } switch (state) { case PM_SUSPEND_MEM: disp_power_down(); usb_power_down_handler(); mxc_cpu_lp_set(ARM_POWER_OFF); arm_pg = true; break; case PM_SUSPEND_STANDBY: if (cpu_is_mx6sl()) { disp_power_down(); usb_power_down_handler(); mxc_cpu_lp_set(STOP_XTAL_ON); arm_pg = true; } else mxc_cpu_lp_set(STOP_POWER_OFF); break; default: return -EINVAL; } /* * L2 can exit by 'reset' or Inband beacon (from remote EP) * toggling phy_powerdown has same effect as 'inband beacon' * So, toggle bit18 of GPR1, to fix errata * "PCIe PCIe does not support L2 Power Down" */ __raw_writel(__raw_readl(IOMUXC_GPR1) | (1 << 18), IOMUXC_GPR1); if (state == PM_SUSPEND_MEM || state == PM_SUSPEND_STANDBY) { local_flush_tlb_all(); flush_cache_all(); if (arm_pg) { /* preserve gic state */ save_gic_dist_state(0, &gds); save_gic_cpu_state(0, &gcs); } if (pm_data && pm_data->suspend_enter) pm_data->suspend_enter(); suspend_in_iram(state, (unsigned long)iram_paddr, (unsigned long)suspend_iram_base, cpu_type); if (pm_data && pm_data->suspend_exit) pm_data->suspend_exit(); /* Reset the RBC counter. */ /* All interrupts should be masked before the * RBC counter is reset. */ /* Mask all interrupts. These will be unmasked by * the mx6_suspend_restore routine below. */ __raw_writel(0xffffffff, gpc_base + 0x08); __raw_writel(0xffffffff, gpc_base + 0x0c); __raw_writel(0xffffffff, gpc_base + 0x10); __raw_writel(0xffffffff, gpc_base + 0x14); /* Clear the RBC counter and RBC_EN bit. */ /* Disable the REG_BYPASS_COUNTER. */ __raw_writel(__raw_readl(MXC_CCM_CCR) & ~MXC_CCM_CCR_RBC_EN, MXC_CCM_CCR); /* Make sure we clear REG_BYPASS_COUNT*/ __raw_writel(__raw_readl(MXC_CCM_CCR) & (~MXC_CCM_CCR_REG_BYPASS_CNT_MASK), MXC_CCM_CCR); /* Need to wait for a minimum of 2 CLKILS (32KHz) for the * counter to clear and reset. */ udelay(80); if (arm_pg) { /* restore gic registers */ restore_gic_dist_state(0, &gds); restore_gic_cpu_state(0, &gcs); } if (state == PM_SUSPEND_MEM || (cpu_is_mx6sl())) { usb_power_up_handler(); disp_power_up(); } mx6_suspend_restore(); __raw_writel(BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG, anatop_base + HW_ANADIG_ANA_MISC0_CLR); } else { cpu_do_idle(); } /* * L2 can exit by 'reset' or Inband beacon (from remote EP) * toggling phy_powerdown has same effect as 'inband beacon' * So, toggle bit18 of GPR1, to fix errata * "PCIe PCIe does not support L2 Power Down" */ __raw_writel(__raw_readl(IOMUXC_GPR1) & (~(1 << 18)), IOMUXC_GPR1); return 0; }
static int __devinit busfreq_probe(struct platform_device *pdev) { u32 err; busfreq_dev = &pdev->dev; pll2_400 = clk_get(NULL, "pll2_pfd_400M"); if (IS_ERR(pll2_400)) { printk(KERN_DEBUG "%s: failed to get pll2_pfd_400M\n", __func__); return PTR_ERR(pll2_400); } pll2_200 = clk_get(NULL, "pll2_200M"); if (IS_ERR(pll2_200)) { printk(KERN_DEBUG "%s: failed to get pll2_200M\n", __func__); return PTR_ERR(pll2_200); } pll2 = clk_get(NULL, "pll2"); if (IS_ERR(pll2)) { printk(KERN_DEBUG "%s: failed to get pll2\n", __func__); return PTR_ERR(pll2); } pll1 = clk_get(NULL, "pll1_main_clk"); if (IS_ERR(pll1)) { printk(KERN_DEBUG "%s: failed to get pll1\n", __func__); return PTR_ERR(pll1); } pll1_sw_clk = clk_get(NULL, "pll1_sw_clk"); if (IS_ERR(pll1_sw_clk)) { printk(KERN_DEBUG "%s: failed to get pll1_sw_clk\n", __func__); return PTR_ERR(pll1_sw_clk); } if (IS_ERR(pll2)) { printk(KERN_DEBUG "%s: failed to get pll2\n", __func__); return PTR_ERR(pll2); } cpu_clk = clk_get(NULL, "cpu_clk"); if (IS_ERR(cpu_clk)) { printk(KERN_DEBUG "%s: failed to get cpu_clk\n", __func__); return PTR_ERR(cpu_clk); } pll3 = clk_get(NULL, "pll3_main_clk"); if (IS_ERR(pll3)) { printk(KERN_DEBUG "%s: failed to get pll3\n", __func__); return PTR_ERR(pll3); } pll3_540 = clk_get(NULL, "pll3_pfd_540M"); if (IS_ERR(pll3_540)) { printk(KERN_DEBUG "%s: failed to get periph_clk\n", __func__); return PTR_ERR(pll3_540); } pll3_sw_clk = clk_get(NULL, "pll3_sw_clk"); if (IS_ERR(pll3_sw_clk)) { printk(KERN_DEBUG "%s: failed to get pll3_sw_clk\n", __func__); return PTR_ERR(pll3_sw_clk); } axi_clk = clk_get(NULL, "axi_clk"); if (IS_ERR(axi_clk)) { printk(KERN_DEBUG "%s: failed to get axi_clk\n", __func__); return PTR_ERR(axi_clk); } ahb_clk = clk_get(NULL, "ahb"); if (IS_ERR(ahb_clk)) { printk(KERN_DEBUG "%s: failed to get ahb_clk\n", __func__); return PTR_ERR(ahb_clk); } periph_clk = clk_get(NULL, "periph_clk"); if (IS_ERR(periph_clk)) { printk(KERN_DEBUG "%s: failed to get periph_clk\n", __func__); return PTR_ERR(periph_clk); } osc_clk = clk_get(NULL, "osc"); if (IS_ERR(osc_clk)) { printk(KERN_DEBUG "%s: failed to get osc_clk\n", __func__); return PTR_ERR(osc_clk); } mmdc_ch0_axi = clk_get(NULL, "mmdc_ch0_axi"); if (IS_ERR(mmdc_ch0_axi)) { printk(KERN_DEBUG "%s: failed to get mmdc_ch0_axi\n", __func__); return PTR_ERR(mmdc_ch0_axi); } err = sysfs_create_file(&busfreq_dev->kobj, &dev_attr_enable.attr); if (err) { printk(KERN_ERR "Unable to register sysdev entry for BUSFREQ"); return err; } cpu_op_tbl = get_cpu_op(&cpu_op_nr); low_bus_freq_mode = 0; if (cpu_is_mx6dl()) { high_bus_freq_mode = 0; med_bus_freq_mode = 1; /* To make pll2_400 use count right, as when system enter 24M, it will disable pll2_400 */ clk_enable(pll2_400); } else if (cpu_is_mx6sl()) { /* Set med_bus_freq_mode to 1 since med_bus_freq_mode is not supported as yet for MX6SL */ high_bus_freq_mode = 1; med_bus_freq_mode = 1; } else { high_bus_freq_mode = 1; med_bus_freq_mode = 0; } bus_freq_scaling_is_active = 0; bus_freq_scaling_initialized = 1; if (cpu_is_mx6q()) { ddr_low_rate = LPAPM_CLK; ddr_med_rate = DDR_MED_CLK; ddr_normal_rate = DDR3_NORMAL_CLK; } if (cpu_is_mx6dl() || cpu_is_mx6sl()) { ddr_low_rate = LPAPM_CLK; ddr_normal_rate = ddr_med_rate = DDR_MED_CLK; } INIT_DELAYED_WORK(&low_bus_freq_handler, reduce_bus_freq_handler); register_pm_notifier(&imx_bus_freq_pm_notifier); if (!cpu_is_mx6sl()) init_mmdc_settings(); else { /* Use preallocated memory */ mx6sl_wfi_iram_phys_addr = MX6SL_WFI_IRAM_CODE; /* * Don't ioremap the address, we have fixed the IRAM address * at IRAM_BASE_ADDR_VIRT */ mx6sl_wfi_iram_base = (void *)IRAM_BASE_ADDR_VIRT + (mx6sl_wfi_iram_phys_addr - IRAM_BASE_ADDR); memcpy(mx6sl_wfi_iram_base, mx6sl_wait, MX6SL_WFI_IRAM_CODE_SIZE); mx6sl_wfi_iram = (void *)mx6sl_wfi_iram_base; /* Use preallocated memory */ mx6sl_ddr_freq_phys_addr = MX6_DDR_FREQ_IRAM_CODE; /* * Don't ioremap the address, we have fixed the IRAM address * at IRAM_BASE_ADDR_VIRT */ mx6sl_ddr_freq_base = (void *)IRAM_BASE_ADDR_VIRT + (mx6sl_ddr_freq_phys_addr - IRAM_BASE_ADDR); memcpy(mx6sl_ddr_freq_base, mx6sl_ddr_iram, MX6SL_DDR_FREQ_CODE_SIZE); mx6sl_ddr_freq_change_iram = (void *)mx6sl_ddr_freq_base; } return 0; }
/* Set the DDR to either 528MHz or 400MHz for MX6q * or 400MHz for MX6DL. */ int set_high_bus_freq(int high_bus_freq) { if (bus_freq_scaling_initialized && bus_freq_scaling_is_active) cancel_delayed_work_sync(&low_bus_freq_handler); if (busfreq_suspended) return 0; if (!bus_freq_scaling_initialized || !bus_freq_scaling_is_active) return 0; if (cpu_is_mx6sl()) high_bus_freq = 1; if (high_bus_freq_mode && high_bus_freq) return 0; /* medium bus freq is only supported for MX6DQ */ if (cpu_is_mx6q() && med_bus_freq_mode && !high_bus_freq) return 0; if (cpu_is_mx6dl() && high_bus_freq) high_bus_freq = 0; if (cpu_is_mx6dl() && med_bus_freq_mode) return 0; if ((high_bus_freq_mode && (high_bus_freq || lp_high_freq)) || (med_bus_freq_mode && !high_bus_freq && lp_med_freq && !lp_high_freq)) return 0; if (cpu_is_mx6sl()) { u32 reg; unsigned long flags; u32 ttbr1; spin_lock_irqsave(&freq_lock, flags); /* sync the outer cache. */ outer_sync(); ttbr1 = save_ttbr1(); /* Change DDR freq in IRAM. */ mx6sl_ddr_freq_change_iram(ddr_normal_rate, low_bus_freq_mode); restore_ttbr1(ttbr1); spin_unlock_irqrestore(&freq_lock, flags); /* Set periph_clk to be sourced from pll2_pfd2_400M */ /* First need to set the divider before changing the */ /* parent if parent clock is larger than previous one */ clk_set_rate(ahb_clk, clk_round_rate(ahb_clk, LPAPM_CLK / 3)); clk_set_rate(axi_clk, clk_round_rate(axi_clk, LPAPM_CLK / 2)); clk_set_parent(periph_clk, pll2_400); if (low_bus_freq_mode) { /* Now move ARM to be sourced from PLL2_400 too. */ clk_set_parent(pll1_sw_clk, pll2_400); /* Ensure that the clock will be at original speed. */ reg = __raw_writel(org_arm_podf, MXC_CCM_CACRR); while (__raw_readl(MXC_CCM_CDHIPR)) ; clk_disable(pll1); } high_bus_freq_mode = 1; low_bus_freq_mode = 0; audio_bus_freq_mode = 0; } else { clk_enable(pll3); if (high_bus_freq) { update_ddr_freq(ddr_normal_rate); /* Make sure periph clk's parent also got updated */ clk_set_parent(periph_clk, pll2); if (med_bus_freq_mode) clk_disable(pll2_400); high_bus_freq_mode = 1; med_bus_freq_mode = 0; } else { clk_enable(pll2_400); update_ddr_freq(ddr_med_rate); /* Make sure periph clk's parent also got updated */ clk_set_parent(periph_clk, pll2_400); high_bus_freq_mode = 0; med_bus_freq_mode = 1; } if (audio_bus_freq_mode) clk_disable(pll2_400); /* AXI_CLK is sourced from PLL3_PFD_540 on MX6DL */ if (cpu_is_mx6dl() && clk_get_parent(axi_clk) != pll3_540) clk_set_parent(axi_clk, pll3_540); low_bus_freq_mode = 0; audio_bus_freq_mode = 0; clk_disable(pll3); } return 0; }