summaryrefslogtreecommitdiff
path: root/drivers/soc
diff options
context:
space:
mode:
authorBai Ping <ping.bai@nxp.com>2018-10-31 09:59:37 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:34:56 +0800
commita906afb17d445b40f6c70fa2a2c3b6707ada0e47 (patch)
tree70db498665a73f36e262c9e922105ecc776f2f4d /drivers/soc
parentc0ed10bebc7883053f058d3849de9fc91b7524d2 (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.c94
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 */