From a906afb17d445b40f6c70fa2a2c3b6707ada0e47 Mon Sep 17 00:00:00 2001 From: Bai Ping Date: Wed, 31 Oct 2018 09:59:37 +0800 Subject: MLK-20136-03 driver: soc: imx: add 100mts support for imx8mq low bus mode The 100MTS low bus mode can be only supported by i.MX8MQ Rev2.1 and future TO. So necessary check is added to identify the chip revision when doing busfreq mode switch. Signed-off-by: Bai Ping Reviewed-by: Anson Huang --- drivers/soc/imx/busfreq-imx8mq.c | 94 ++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 19 deletions(-) diff --git a/drivers/soc/imx/busfreq-imx8mq.c b/drivers/soc/imx/busfreq-imx8mq.c index a8c3488d0b4c..7624764dbaa1 100644 --- a/drivers/soc/imx/busfreq-imx8mq.c +++ b/drivers/soc/imx/busfreq-imx8mq.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #define HIGH_FREQ_3200MTS 0x0 #define AUDIO_FREQ_400MTS 0x1 @@ -113,15 +115,32 @@ static void reduce_bus_freq(void) if (cur_bus_freq_mode == BUS_FREQ_HIGH) { if (of_machine_is_compatible("fsl,imx8mq")) { - update_bus_freq(LOW_BUS_FREQ_667MTS); - - /* - * the dram_apb and dram_core clk rate is changed - * in ATF side, below two lines of code is just used - * to upate the clock tree info in kernel side. - */ - clk_set_rate(dram_apb_pre_div, 160000000); - clk_get_rate(dram_pll_clk); + if (imx8_get_soc_revision() < IMX_CHIP_REVISION_2_1) { + update_bus_freq(LOW_BUS_FREQ_667MTS); + + /* + * the dram_apb and dram_core clk rate is changed + * in ATF side, below two lines of code is just used + * to upate the clock tree info in kernel side. + */ + clk_set_rate(dram_apb_pre_div, 160000000); + clk_get_rate(dram_pll_clk); + } else { + /* prepare the necessary clk before frequency change */ + clk_prepare_enable(sys1_pll_40m); + clk_prepare_enable(dram_alt_root); + clk_prepare_enable(sys1_pll_100m); + + update_bus_freq(LOW_BUS_FREQ_100MTS); + + clk_set_parent(dram_alt_src, sys1_pll_100m); + clk_set_parent(dram_core_clk, dram_alt_root); + clk_set_parent(dram_apb_src, sys1_pll_40m); + clk_set_rate(dram_apb_pre_div, 20000000); + clk_disable_unprepare(sys1_pll_100m); + clk_disable_unprepare(sys1_pll_40m); + clk_disable_unprepare(dram_alt_root); + } /* reduce the NOC & bus clock */ clk_set_rate(noc_div, clk_get_rate(noc_div) / 8); } else { @@ -154,12 +173,33 @@ static void reduce_bus_freq(void) cur_bus_freq_mode = BUS_FREQ_AUDIO; } else { if (cur_bus_freq_mode == BUS_FREQ_HIGH) { - if (of_machine_is_compatible("fsl,imx8mq")) { - update_bus_freq(LOW_BUS_FREQ_667MTS); - - clk_set_rate(dram_apb_pre_div, 160000000); - clk_get_rate(dram_pll_clk); + if (imx8_get_soc_revision() < IMX_CHIP_REVISION_2_1) { + update_bus_freq(LOW_BUS_FREQ_667MTS); + + /* + * the dram_apb and dram_core clk rate is changed + * in ATF side, below two lines of code is just used + * to upate the clock tree info in kernel side. + */ + clk_set_rate(dram_apb_pre_div, 160000000); + clk_get_rate(dram_pll_clk); + } else { + /* prepare the necessary clk before frequency change */ + clk_prepare_enable(sys1_pll_40m); + clk_prepare_enable(dram_alt_root); + clk_prepare_enable(sys1_pll_100m); + + update_bus_freq(LOW_BUS_FREQ_100MTS); + + clk_set_parent(dram_alt_src, sys1_pll_100m); + clk_set_parent(dram_core_clk, dram_alt_root); + clk_set_parent(dram_apb_src, sys1_pll_40m); + clk_set_rate(dram_apb_pre_div, 20000000); + clk_disable_unprepare(sys1_pll_100m); + clk_disable_unprepare(sys1_pll_40m); + clk_disable_unprepare(dram_alt_root); + } /* reduce the NOC & bus clock */ clk_set_rate(noc_div, clk_get_rate(noc_div) / 8); } else { @@ -253,11 +293,27 @@ static int set_high_bus_freq(int high_bus_freq) return 0; if (of_machine_is_compatible("fsl,imx8mq")) { - /* switch the DDR freqeuncy */ - update_bus_freq(HIGH_FREQ_3200MTS); - - clk_set_rate(dram_apb_pre_div, 200000000); - clk_get_rate(dram_pll_clk); + if (imx8_get_soc_revision() < IMX_CHIP_REVISION_2_1) { + /* switch the DDR freqeuncy */ + update_bus_freq(HIGH_FREQ_3200MTS); + + clk_set_rate(dram_apb_pre_div, 200000000); + clk_get_rate(dram_pll_clk); + } else { + /* enable the clks needed in frequency */ + clk_prepare_enable(sys1_pll_800m); + clk_prepare_enable(dram_pll_clk); + + /* switch the DDR freqeuncy */ + update_bus_freq(HIGH_FREQ_3200MTS); + + /* correct the clock tree info */ + clk_set_parent(dram_apb_src, sys1_pll_800m); + clk_set_rate(dram_apb_pre_div, 160000000); + clk_set_parent(dram_core_clk, dram_pll_clk); + clk_disable_unprepare(sys1_pll_800m); + clk_disable_unprepare(dram_pll_clk); + } clk_set_rate(noc_div, 800000000); } else { /* enable the clks needed in frequency */ -- cgit v1.2.3