/* * enter_lpm_imx6_up and exit_lpm_imx6_up is used by * i.MX6SX/i.MX6UL for entering and exiting lpm mode. */ static void enter_lpm_imx6_up(void) { if (cpu_is_imx6sx() && imx_src_is_m4_enabled()) if (!check_m4_sleep()) pr_err("M4 is NOT in sleep!!!\n"); /* set periph_clk2 to source from OSC for periph */ imx_clk_set_parent(periph_clk2_sel, osc_clk); imx_clk_set_parent(periph_clk, periph_clk2); /* set ahb/ocram to 24MHz */ imx_clk_set_rate(ahb_clk, LPAPM_CLK); imx_clk_set_rate(ocram_clk, LPAPM_CLK); if (audio_bus_count) { /* Need to ensure that PLL2_PFD_400M is kept ON. */ clk_prepare_enable(pll2_400); if (ddr_type == MMDC_MDMISC_DDR_TYPE_DDR3) update_ddr_freq_imx6_up(LOW_AUDIO_CLK); else if (ddr_type == MMDC_MDMISC_DDR_TYPE_LPDDR2) update_lpddr2_freq(HIGH_AUDIO_CLK); imx_clk_set_parent(periph2_clk2_sel, pll3); imx_clk_set_parent(periph2_pre_clk, pll2_400); imx_clk_set_parent(periph2_clk, periph2_pre_clk); /* * As periph2_clk's parent is not changed from * high mode to audio mode, so clk framework * will not update its children's freq, but we * change the mmdc's podf in asm code, so here * need to update mmdc rate to make sure clk * tree is right, although it will not do any * change to hardware. */ if (high_bus_freq_mode) { if (ddr_type == MMDC_MDMISC_DDR_TYPE_DDR3) imx_clk_set_rate(mmdc_clk, LOW_AUDIO_CLK); else if (ddr_type == MMDC_MDMISC_DDR_TYPE_LPDDR2) imx_clk_set_rate(mmdc_clk, HIGH_AUDIO_CLK); } audio_bus_freq_mode = 1; low_bus_freq_mode = 0; cur_bus_freq_mode = BUS_FREQ_AUDIO; } else { if (ddr_type == MMDC_MDMISC_DDR_TYPE_DDR3) update_ddr_freq_imx6_up(LPAPM_CLK); else if (ddr_type == MMDC_MDMISC_DDR_TYPE_LPDDR2) update_lpddr2_freq(LPAPM_CLK); imx_clk_set_parent(periph2_clk2_sel, osc_clk); imx_clk_set_parent(periph2_clk, periph2_clk2); if (audio_bus_freq_mode) clk_disable_unprepare(pll2_400); low_bus_freq_mode = 1; audio_bus_freq_mode = 0; cur_bus_freq_mode = BUS_FREQ_LOW; } }
static void exit_lpm_imx6_up(void) { clk_prepare_enable(pll2_400); /* * lower ahb/ocram's freq first to avoid too high * freq during parent switch from OSC to pll3. */ if (cpu_is_imx6ul()) imx_clk_set_rate(ahb_clk, LPAPM_CLK / 4); else imx_clk_set_rate(ahb_clk, LPAPM_CLK / 3); imx_clk_set_rate(ocram_clk, LPAPM_CLK / 2); /* set periph clk to from pll2_bus on i.MX6UL */ if (cpu_is_imx6ul()) imx_clk_set_parent(periph_pre_clk, pll2_bus); /* set periph clk to from pll2_400 */ else imx_clk_set_parent(periph_pre_clk, pll2_400); imx_clk_set_parent(periph_clk, periph_pre_clk); /* set periph_clk2 to pll3 */ imx_clk_set_parent(periph_clk2_sel, pll3); if (ddr_type == MMDC_MDMISC_DDR_TYPE_DDR3) update_ddr_freq_imx6_up(ddr_normal_rate); else if (ddr_type == MMDC_MDMISC_DDR_TYPE_LPDDR2) update_lpddr2_freq(ddr_normal_rate); /* correct parent info after ddr freq change in asm code */ imx_clk_set_parent(periph2_pre_clk, pll2_400); imx_clk_set_parent(periph2_clk, periph2_pre_clk); imx_clk_set_parent(periph2_clk2_sel, pll3); /* * As periph2_clk's parent is not changed from * audio mode to high mode, so clk framework * will not update its children's freq, but we * change the mmdc's podf in asm code, so here * need to update mmdc rate to make sure clk * tree is right, although it will not do any * change to hardware. */ if (audio_bus_freq_mode) imx_clk_set_rate(mmdc_clk, ddr_normal_rate); clk_disable_unprepare(pll2_400); if (audio_bus_freq_mode) clk_disable_unprepare(pll2_400); }