diff options
author | Bai Ping <ping.bai@nxp.com> | 2018-10-31 09:59:37 +0800 |
---|---|---|
committer | Jason Liu <jason.hui.liu@nxp.com> | 2019-02-12 10:34:56 +0800 |
commit | a906afb17d445b40f6c70fa2a2c3b6707ada0e47 (patch) | |
tree | 70db498665a73f36e262c9e922105ecc776f2f4d /drivers/soc | |
parent | c0ed10bebc7883053f058d3849de9fc91b7524d2 (diff) |
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 <ping.bai@nxp.com>
Reviewed-by: Anson Huang <Anson.Huang@nxp.com>
Diffstat (limited to 'drivers/soc')
-rw-r--r-- | drivers/soc/imx/busfreq-imx8mq.c | 94 |
1 files 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 <linux/smp.h> #include <linux/suspend.h> #include <soc/imx/fsl_sip.h> +#include <soc/imx/revision.h> +#include <soc/imx8/soc.h> #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 */ |