[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/kernel/linux/v4.14/drivers/devfreq/mediatek/Makefile b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/Makefile
new file mode 100644
index 0000000..afc3706
--- /dev/null
+++ b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/Makefile
@@ -0,0 +1,14 @@
+#
+# Copyright (C) 2018 MediaTek Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+
+obj-$(CONFIG_MACH_MT2731) += mt2731/
diff --git a/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/Makefile b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/Makefile
new file mode 100644
index 0000000..c3630db
--- /dev/null
+++ b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/Makefile
@@ -0,0 +1,26 @@
+
+#
+# Copyright (C) 2018 MediaTek Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+MTK_PLATFORM := $(subst ",,$(CONFIG_MTK_PLATFORM))
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/$(MTK_PLATFORM)/include
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/include/mt-plat/
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/dramc/$(MTK_PLATFORM)/
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/emi/$(MTK_PLATFORM)
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/emi/submodule/
+
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/base/power/spm/$(MTK_PLATFORM)/inc
+ccflags-y += -I$(srctree)/drivers/devfreq/
+
+obj-y += mtk-dvfsrc-opp.o mtk-dvfsrc-sysfs.o
+obj-y += mtk-dvfsrc_v2.o mtk-dvfsrc-$(MTK_PLATFORM).o mtk-dvfsrc-opp-$(MTK_PLATFORM).o
diff --git a/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-mt2731.c b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-mt2731.c
new file mode 100644
index 0000000..7d02225
--- /dev/null
+++ b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-mt2731.c
@@ -0,0 +1,637 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+#include <linux/fb.h>
+#include <linux/notifier.h>
+#include <linux/string.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/sched/clock.h>
+#include <linux/sched.h>
+
+
+#ifdef CONFIG_MTK_DRAMC
+#include <mtk_dramc.h>
+#endif
+#ifdef CONFIG_MTK_PMIC_COMMON
+#include <mt-plat/upmu_common.h>
+#endif
+#ifdef CONFIG_MTK_WATCHDOG
+#include <ext_wd_drv.h>
+#endif
+#ifdef CONFIG_MTK_EMI
+#include <mt_emi_api.h>
+#endif
+
+#include "mtk-dvfsrc.h"
+#include "mtk-dvfsrc-opp.h"
+#include "mtk-dvfsrc_reg.h"
+#include <mtk_spm_internal.h>
+#include <mtk_vcore_dvfs.h>
+#include <linux/mutex.h>
+
+#ifdef CONFIG_MTK_AEE_FEATURE
+#include <mt-plat/aee.h>
+#endif
+#if 0
+#include <mmdvfs_mgr.h>
+#include <mtk_qos_sram.h>
+#endif
+
+static DEFINE_SPINLOCK(force_req_lock);
+static char opp_forced;
+
+static void dvfsrc_set_sw_req(int data, int mask, int shift)
+{
+ dvfsrc_rmw(DVFSRC_SW_REQ, data, mask, shift);
+}
+
+static int is_dvfsrc_forced(void)
+{
+ return opp_forced;
+}
+
+static void dvfsrc_set_force_start(int data)
+{
+ opp_forced = 1;
+ dvfsrc_rmw(DVFSRC_BASIC_CONTROL, 0,
+ DVFSRC_OUT_EN_MASK, DVFSRC_OUT_EN_SHIFT);
+ dvfsrc_rmw(DVFSRC_BASIC_CONTROL, 0,
+ FORCE_EN_TAR_MASK, FORCE_EN_TAR_SHIFT);
+ dvfsrc_rmw(DVFSRC_FORCE, data, TARGET_FORCE_MASK, TARGET_FORCE_SHIFT);
+ dvfsrc_rmw(DVFSRC_BASIC_CONTROL, 1,
+ FORCE_EN_TAR_MASK, FORCE_EN_TAR_SHIFT);
+ dvfsrc_rmw(DVFSRC_BASIC_CONTROL, 1,
+ DVFSRC_OUT_EN_MASK, DVFSRC_OUT_EN_SHIFT);
+}
+
+static void dvfsrc_set_force_end(void)
+{
+ dvfsrc_rmw(DVFSRC_BASIC_CONTROL, 0,
+ DVFSRC_OUT_EN_MASK, DVFSRC_OUT_EN_SHIFT);
+ dvfsrc_rmw(DVFSRC_BASIC_CONTROL, 0,
+ FORCE_EN_TAR_MASK, FORCE_EN_TAR_SHIFT);
+ dvfsrc_rmw(DVFSRC_FORCE, 0, TARGET_FORCE_MASK, TARGET_FORCE_SHIFT);
+ dvfsrc_rmw(DVFSRC_BASIC_CONTROL, 1,
+ FORCE_EN_TAR_MASK, FORCE_EN_TAR_SHIFT);
+ dvfsrc_rmw(DVFSRC_BASIC_CONTROL, 1,
+ DVFSRC_OUT_EN_MASK, DVFSRC_OUT_EN_SHIFT);
+}
+
+static void dvfsrc_release_force(void)
+{
+ dvfsrc_rmw(DVFSRC_BASIC_CONTROL, 0,
+ DVFSRC_OUT_EN_MASK, DVFSRC_OUT_EN_SHIFT);
+ dvfsrc_rmw(DVFSRC_BASIC_CONTROL, 0,
+ FORCE_EN_TAR_MASK, FORCE_EN_TAR_SHIFT);
+ dvfsrc_rmw(DVFSRC_BASIC_CONTROL, 0,
+ FORCE_EN_CUR_MASK, FORCE_EN_CUR_SHIFT);
+
+ dvfsrc_write(DVFSRC_FORCE, 0);
+ dvfsrc_rmw(DVFSRC_BASIC_CONTROL, 1,
+ DVFSRC_OUT_EN_MASK, DVFSRC_OUT_EN_SHIFT);
+ opp_forced = 0;
+}
+
+int commit_data(int type, int data)
+{
+ int ret = 0;
+ int level = 16, opp = 16;
+ unsigned long flags;
+ u32 current_level;
+
+ if (!is_dvfsrc_enabled())
+ return ret;
+
+ switch (type) {
+ case DVFSRC_DDR_OPP:
+ spin_lock_irqsave(&force_req_lock, flags);
+ if (data >= DDR_OPP_NUM || data < 0)
+ data = DDR_OPP_NUM - 1;
+
+ opp = data;
+ level = DDR_OPP_NUM - data - 1;
+
+ dvfsrc_set_sw_req(level, EMI_SW_AP_MASK, EMI_SW_AP_SHIFT);
+
+ if (!is_dvfsrc_forced()) {
+ ret = dvfsrc_wait_for_completion(
+ get_cur_ddr_opp() <= opp,
+ DVFSRC_TIMEOUT);
+ }
+ spin_unlock_irqrestore(&force_req_lock, flags);
+ break;
+ case DVFSRC_VCORE_OPP:
+ spin_lock_irqsave(&force_req_lock, flags);
+ if (data >= VCORE_OPP_NUM || data < 0)
+ data = VCORE_OPP_NUM - 1;
+
+ opp = data;
+ level = VCORE_OPP_NUM - data - 1;
+
+ dvfsrc_set_sw_req(level, VCORE_SW_AP_MASK, VCORE_SW_AP_SHIFT);
+
+ if (!is_dvfsrc_forced()) {
+ ret = dvfsrc_wait_for_completion(
+ get_cur_vcore_opp() <= opp,
+ DVFSRC_TIMEOUT);
+ }
+ spin_unlock_irqrestore(&force_req_lock, flags);
+ break;
+ case DVFSRC_VCORE_DVFS_FORCE_OPP:
+ spin_lock_irqsave(&force_req_lock, flags);
+ if (data >= VCORE_DVFS_OPP_NUM || data < 0)
+ data = VCORE_DVFS_OPP_NUM;
+
+ opp = data;
+ level = data;
+
+ if (opp == VCORE_DVFS_OPP_NUM) {
+ dvfsrc_release_force();
+ spin_unlock_irqrestore(&force_req_lock, flags);
+ break;
+ }
+ dvfsrc_set_force_start(1 << level);
+ ret = dvfsrc_wait_for_completion(
+ get_cur_vcore_dvfs_opp() == opp,
+ DVFSRC_TIMEOUT);
+
+ dvfsrc_set_force_end();
+ spin_unlock_irqrestore(&force_req_lock, flags);
+ break;
+ case DVFSRC_VCORE_DVFS_FORCE_OPP_WORKAROUND:
+ spin_lock_irqsave(&force_req_lock, flags);
+
+ current_level = (dvfsrc_read(DVFSRC_LEVEL)
+ & CURRENT_LEVEL_MASK) >> CURRENT_LEVEL_SHIFT;
+
+ dvfsrc_set_force_start(current_level);
+ ret = dvfsrc_wait_for_completion(
+ get_cur_vcore_dvfs_opp() == opp,
+ DVFSRC_TIMEOUT);
+
+ dvfsrc_set_force_end();
+
+ dvfsrc_release_force();
+
+ spin_unlock_irqrestore(&force_req_lock, flags);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+void dvfsrc_update_md_scenario(bool blank)
+{
+ if (blank)
+ dvfsrc_write(DVFSRC_MD_TURBO, 0x1FFF0000);
+ else
+ dvfsrc_write(DVFSRC_MD_TURBO, 0x00000000);
+}
+
+static int dvfsrc_fb_notifier_call(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ struct fb_event *evdata = data;
+ int blank;
+
+ if (event != FB_EVENT_BLANK)
+ return 0;
+
+ blank = *(int *)evdata->data;
+
+ switch (blank) {
+ case FB_BLANK_UNBLANK:
+ dvfsrc_update_md_scenario(false);
+ break;
+ case FB_BLANK_POWERDOWN:
+ dvfsrc_update_md_scenario(true);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static struct notifier_block dvfsrc_fb_notifier = {
+ .notifier_call = dvfsrc_fb_notifier_call,
+};
+
+#ifdef AUTOK_ENABLE
+__weak int emmc_autok(void)
+{
+ pr_info("NOT SUPPORT EMMC AUTOK(%s)\n", __func__);
+ return 0;
+}
+
+__weak int sd_autok(void)
+{
+ pr_info("NOT SUPPORT SD AUTOK(%s)\n", __func__);
+ return 0;
+}
+
+__weak int sdio_autok(void)
+{
+ pr_info("NOT SUPPORT SDIO AUTOK(%s)\n", __func__);
+ return 0;
+}
+
+
+void begin_autok_task(void)
+{
+#if 0
+ struct mmdvfs_prepare_event evt_from_vcore = {
+ MMDVFS_EVENT_PREPARE_CALIBRATION_START};
+
+ /* notify MM DVFS for msdc autok start */
+ mmdvfs_notify_prepare_action(&evt_from_vcore);
+#endif
+}
+
+void finish_autok_task(void)
+{
+ int force;
+
+ /* check if dvfs force is released */
+ force = dvfsrc_get_reguest(DVFSRC_VCORE_DVFS_FORCE_OPP);
+#if 0
+ struct mmdvfs_prepare_event evt_from_vcore = {
+ MMDVFS_EVENT_PREPARE_CALIBRATION_END};
+
+ /* notify MM DVFS for msdc autok finish */
+ mmdvfs_notify_prepare_action(&evt_from_vcore);
+#endif
+ if (force >= 0 && force < 12)
+ pr_info("autok task not release force opp: %d\n", force);
+}
+
+void dvfsrc_autok_manager(void)
+{
+ int r = 0;
+
+ begin_autok_task();
+
+ r = emmc_autok();
+ pr_info("EMMC autok done: %s\n", (r == 0) ? "Yes" : "No");
+
+ r = sd_autok();
+ pr_info("SD autok done: %s\n", (r == 0) ? "Yes" : "No");
+
+ r = sdio_autok();
+ pr_info("SDIO autok done: %s\n", (r == 0) ? "Yes" : "No");
+
+ finish_autok_task();
+}
+#endif
+
+
+static irqreturn_t dvfsrc_interrupt(int irq, void *dev_id)
+{
+ u32 val;
+
+ pr_info("[DVFSRC] IRQ HANDLER SHOULD NOT BE EXECUTED\n");
+ val = dvfsrc_read(DVFSRC_INT);
+ if (val & TIMEOUT_INT_MASK)
+ dvfsrc_dump_reg(NULL);
+
+ dvfsrc_write(DVFSRC_INT_CLR, dvfsrc_read(DVFSRC_INT));
+ dvfsrc_write(DVFSRC_INT_CLR, 0x0);
+
+ return IRQ_HANDLED;
+}
+
+int dvfsrc_platform_init(struct dvfsrc *dvfsrc)
+{
+ struct device_node *node;
+ int irq;
+ int ret;
+
+#ifdef CONFIG_MTK_WATCHDOG
+ mtk_rgu_cfg_dvfsrc(1);
+#endif
+
+ dvfsrc_enable(1);
+
+#ifdef AUTOK_ENABLE
+ dvfsrc_autok_manager();
+#endif
+ fb_register_client(&dvfsrc_fb_notifier);
+
+ node = of_find_compatible_node(NULL, NULL, "mediatek,dvfsrc");
+ if (!node)
+ pr_info("[DVFSRC] find DVSFRC node failed\n");
+
+ irq = irq_of_parse_and_map(node, 0);
+ if (!irq)
+ pr_info("[DVFSRC] get DVFSRC IRQ failed\n");
+
+ ret = request_irq(irq, dvfsrc_interrupt,
+ IRQF_TRIGGER_HIGH, "DVFSRC", NULL);
+
+ if (ret)
+ pr_info("[DVFSRC] FAILED TO REQUEST IRQ(%d)\n", ret);
+
+ return 0;
+}
+
+void get_opp_info(char *p)
+{
+ int vcore_uv = 0;
+#ifdef CONFIG_MTK_PMIC_COMMON
+ int pmic_val = 0;
+
+ pmic_val = pmic_get_register_value(PMIC_VCORE_ADDR);
+ vcore_uv = vcore_pmic_to_uv(pmic_val);
+#endif
+#if defined(CONFIG_MTK_DRAMC)
+ unsigned int ddr_hz = get_dram_data_rate();
+ int ddr_type = get_ddr_type();
+#endif
+
+ p += sprintf(p, "%-24s: %-8u uv (PMIC: 0x%x)\n",
+ "Vcore", vcore_uv, vcore_uv_to_pmic(vcore_uv));
+
+#if defined(CONFIG_MTK_DRAMC)
+ if (ddr_type == TYPE_LPDDR4X)
+ p += sprintf(p, "%-24s: LPDDR4X %-8u hz\n", "DDR", ddr_hz);
+ else if (ddr_type == TYPE_LPDDR2)
+ p += sprintf(p, "%-24s: LPDDR2 %-8u hz\n", "DDR", ddr_hz);
+ else
+ p += sprintf(p, "%-24s: UNKNOWN DDR %-8u hz\n", "DDR", ddr_hz);
+#endif
+}
+
+void get_dvfsrc_reg(char *p)
+{
+ p += sprintf(p, "%-24s: 0x%08x\n",
+ "DVFSRC_BASIC_CONTROL",
+ dvfsrc_read(DVFSRC_BASIC_CONTROL));
+ p += sprintf(p, "%-24s: 0x%08x\n",
+ "DVFSRC_SW_REQ",
+ dvfsrc_read(DVFSRC_SW_REQ));
+ p += sprintf(p, "%-24s: 0x%08x\n",
+ "DVFSRC_SW_REQ2",
+ dvfsrc_read(DVFSRC_SW_REQ2));
+ p += sprintf(p, "%-24s: 0x%08x\n",
+ "DVFSRC_SEC_SW_REQ",
+ dvfsrc_read(DVFSRC_SEC_SW_REQ));
+ p += sprintf(p, "%-24s: 0x%08x, 0x%08x\n",
+ "DVFSRC_VCORE_REQUEST(2)",
+ dvfsrc_read(DVFSRC_VCORE_REQUEST),
+ dvfsrc_read(DVFSRC_VCORE_REQUEST2));
+ p += sprintf(p, "%-24s: 0x%08x, 0x%08x, 0x%08x\n",
+ "DVFSRC_VCORE_MD2SPM0~2",
+ dvfsrc_read(DVFSRC_VCORE_MD2SPM0),
+ dvfsrc_read(DVFSRC_VCORE_MD2SPM1),
+ dvfsrc_read(DVFSRC_VCORE_MD2SPM2));
+ p += sprintf(p, "%-24s: 0x%08x, 0x%08x, 0x%08x\n",
+ "DVFSRC_VCORE_MD2SPM0~2_T",
+ dvfsrc_read(DVFSRC_VCORE_MD2SPM0_T),
+ dvfsrc_read(DVFSRC_VCORE_MD2SPM1_T),
+ dvfsrc_read(DVFSRC_VCORE_MD2SPM2_T));
+ p += sprintf(p, "%-24s: 0x%08x\n",
+ "DVFSRC_MD_REQUEST",
+ dvfsrc_read(DVFSRC_MD_REQUEST));
+ p += sprintf(p, "%-24s: 0x%08x\n",
+ "DVFSRC_INT",
+ dvfsrc_read(DVFSRC_INT));
+ p += sprintf(p, "%-24s: 0x%08x\n",
+ "DVFSRC_INT_EN",
+ dvfsrc_read(DVFSRC_INT_EN));
+ p += sprintf(p, "%-24s: 0x%08x\n",
+ "DVFSRC_LEVEL",
+ dvfsrc_read(DVFSRC_LEVEL));
+ p += sprintf(p, "%-24s: %d, %d, %d, %d, %d\n",
+ "DVFSRC_SW_BW_0~4",
+ dvfsrc_read(DVFSRC_SW_BW_0),
+ dvfsrc_read(DVFSRC_SW_BW_1),
+ dvfsrc_read(DVFSRC_SW_BW_2),
+ dvfsrc_read(DVFSRC_SW_BW_3),
+ dvfsrc_read(DVFSRC_SW_BW_4));
+}
+
+void get_dvfsrc_record(char *p)
+{
+ p += sprintf(p, "%-24s: 0x%08x\n",
+ "DVFSRC_FORCE",
+ dvfsrc_read(DVFSRC_FORCE));
+ p += sprintf(p, "%-24s: 0x%08x\n",
+ "DVFSRC_SEC_SW_REQ",
+ dvfsrc_read(DVFSRC_SEC_SW_REQ));
+ p += sprintf(p, "%-24s: 0x%08x\n",
+ "DVFSRC_LAST",
+ dvfsrc_read(DVFSRC_LAST));
+ p += sprintf(p, "%-24s: 0x%08x\n",
+ "DVFSRC_MD_SCENARIO",
+ dvfsrc_read(DVFSRC_MD_SCENARIO));
+ p += sprintf(p, "%-24s: 0x%08x, 0x%08x, 0x%08x\n",
+ "DVFSRC_RECORD_0_0~0_2",
+ dvfsrc_read(DVFSRC_RECORD_0_0),
+ dvfsrc_read(DVFSRC_RECORD_0_1),
+ dvfsrc_read(DVFSRC_RECORD_0_2));
+ p += sprintf(p, "%-24s: 0x%08x, 0x%08x, 0x%08x\n",
+ "DVFSRC_RECORD_1_0~1_2",
+ dvfsrc_read(DVFSRC_RECORD_1_0),
+ dvfsrc_read(DVFSRC_RECORD_1_1),
+ dvfsrc_read(DVFSRC_RECORD_1_2));
+ p += sprintf(p, "%-24s: 0x%08x, 0x%08x, 0x%08x\n",
+ "DVFSRC_RECORD_2_0~2_2",
+ dvfsrc_read(DVFSRC_RECORD_2_0),
+ dvfsrc_read(DVFSRC_RECORD_2_1),
+ dvfsrc_read(DVFSRC_RECORD_2_2));
+ p += sprintf(p, "%-24s: 0x%08x, 0x%08x, 0x%08x\n",
+ "DVFSRC_RECORD_3_0~3_2",
+ dvfsrc_read(DVFSRC_RECORD_3_0),
+ dvfsrc_read(DVFSRC_RECORD_3_1),
+ dvfsrc_read(DVFSRC_RECORD_3_2));
+ p += sprintf(p, "%-24s: 0x%08x, 0x%08x, 0x%08x\n",
+ "DVFSRC_RECORD_4_0~4_2",
+ dvfsrc_read(DVFSRC_RECORD_4_0),
+ dvfsrc_read(DVFSRC_RECORD_4_1),
+ dvfsrc_read(DVFSRC_RECORD_4_2));
+ p += sprintf(p, "%-24s: 0x%08x, 0x%08x, 0x%08x\n",
+ "DVFSRC_RECORD_5_0~5_2",
+ dvfsrc_read(DVFSRC_RECORD_5_0),
+ dvfsrc_read(DVFSRC_RECORD_5_1),
+ dvfsrc_read(DVFSRC_RECORD_5_2));
+ p += sprintf(p, "%-24s: 0x%08x, 0x%08x, 0x%08x\n",
+ "DVFSRC_RECORD_6_0~6_2",
+ dvfsrc_read(DVFSRC_RECORD_6_0),
+ dvfsrc_read(DVFSRC_RECORD_6_1),
+ dvfsrc_read(DVFSRC_RECORD_6_2));
+ p += sprintf(p, "%-24s: 0x%08x, 0x%08x, 0x%08x\n",
+ "DVFSRC_RECORD_7_0~7_2",
+ dvfsrc_read(DVFSRC_RECORD_7_0),
+ dvfsrc_read(DVFSRC_RECORD_7_1),
+ dvfsrc_read(DVFSRC_RECORD_7_2));
+ p += sprintf(p, "%-24s: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+ "DVFSRC_RECORD_MD_0~3",
+ dvfsrc_read(DVFSRC_RECORD_MD_0),
+ dvfsrc_read(DVFSRC_RECORD_MD_1),
+ dvfsrc_read(DVFSRC_RECORD_MD_2),
+ dvfsrc_read(DVFSRC_RECORD_MD_3));
+ p += sprintf(p, "%-24s: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+ "DVFSRC_RECORD_MD_4~7",
+ dvfsrc_read(DVFSRC_RECORD_MD_4),
+ dvfsrc_read(DVFSRC_RECORD_MD_5),
+ dvfsrc_read(DVFSRC_RECORD_MD_6),
+ dvfsrc_read(DVFSRC_RECORD_MD_7));
+ p += sprintf(p, "%-24s: 0x%08x\n",
+ "DVFSRC_RECORD_COUNT",
+ dvfsrc_read(DVFSRC_RECORD_COUNT));
+ p += sprintf(p, "%-24s: 0x%08x\n",
+ "DVFSRC_RSRV_0",
+ dvfsrc_read(DVFSRC_RSRV_0));
+}
+
+/* met profile table */
+unsigned int met_vcorefs_info[INFO_MAX];
+unsigned int met_vcorefs_src[SRC_MAX];
+
+char *met_info_name[INFO_MAX] = {
+ "OPP",
+ "FREQ",
+ "VCORE",
+ "SPM_LEVEL",
+};
+
+char *met_src_name[SRC_MAX] = {
+ "MD2SPM",
+ "QOS_EMI_LEVEL",
+ "QOS_VCORE_LEVEL",
+ "CM_MGR_LEVEL",
+ "TOTAL_EMI_LEVEL_1",
+ "TOTAL_EMI_LEVEL_2",
+ "TOTAL_EMI_RESULT",
+ "QOS_BW_LEVEL1",
+ "QOS_BW_LEVEL2",
+ "QOS_BW_RESULT",
+ "SCP_VCORE_LEVEL",
+};
+
+/* met profile function */
+int vcorefs_get_num_opp(void)
+{
+ return VCORE_DVFS_OPP_NUM;
+}
+EXPORT_SYMBOL(vcorefs_get_num_opp);
+
+
+int vcorefs_get_opp_info_num(void)
+{
+ return INFO_MAX;
+}
+EXPORT_SYMBOL(vcorefs_get_opp_info_num);
+
+int vcorefs_get_src_req_num(void)
+{
+ return SRC_MAX;
+}
+EXPORT_SYMBOL(vcorefs_get_src_req_num);
+
+char **vcorefs_get_opp_info_name(void)
+{
+ return met_info_name;
+}
+EXPORT_SYMBOL(vcorefs_get_opp_info_name);
+
+char **vcorefs_get_src_req_name(void)
+{
+ return met_src_name;
+}
+EXPORT_SYMBOL(vcorefs_get_src_req_name);
+
+unsigned int *vcorefs_get_opp_info(void)
+{
+ met_vcorefs_info[INFO_OPP_IDX] = get_cur_vcore_dvfs_opp();
+ met_vcorefs_info[INFO_FREQ_IDX] = get_cur_ddr_khz();
+ met_vcorefs_info[INFO_VCORE_IDX] = get_cur_vcore_uv();
+ met_vcorefs_info[INFO_SPM_LEVEL_IDX] = spm_get_dvfs_level();
+ return met_vcorefs_info;
+}
+EXPORT_SYMBOL(vcorefs_get_opp_info);
+
+__weak void dvfsrc_trace_dbg_show_request(int dvfsrc_class)
+{
+ pr_info("NOT SUPPORT %s\n", __func__);
+}
+
+static DEFINE_RATELIMIT_STATE(tracelimit, 5 * HZ, 1);
+
+static void vcorefs_trace_qos(void)
+{
+ if (__ratelimit(&tracelimit)) {
+ dvfsrc_trace_dbg_show_request(DVFSRC_DDR_OPP);
+ dvfsrc_trace_dbg_show_request(DVFSRC_VCORE_OPP);
+ }
+}
+
+unsigned int *vcorefs_get_src_req(void)
+{
+ unsigned int qos_total_bw = dvfsrc_read(DVFSRC_SW_BW_0) +
+ dvfsrc_read(DVFSRC_SW_BW_1) +
+ dvfsrc_read(DVFSRC_SW_BW_2) +
+ dvfsrc_read(DVFSRC_SW_BW_3) +
+ dvfsrc_read(DVFSRC_SW_BW_4);
+#ifdef CONFIG_MTK_EMI
+ unsigned int total_bw_status = get_emi_bwst(0);
+ unsigned int total_bw_last = (get_emi_bwvl(0) & 0x7F) * 813;
+#endif
+ unsigned int qos0_thres = dvfsrc_read(DVFSRC_EMI_QOS0);
+ unsigned int qos1_thres = dvfsrc_read(DVFSRC_EMI_QOS1);
+ unsigned int sw_req = dvfsrc_read(DVFSRC_SW_REQ);
+
+ met_vcorefs_src[SRC_MD2SPM_IDX] =
+ spm_vcorefs_get_MD_status();
+
+ met_vcorefs_src[SRC_QOS_EMI_LEVEL_IDX] =
+ (sw_req >> EMI_SW_AP_SHIFT) & EMI_SW_AP_MASK;
+
+ met_vcorefs_src[SRC_QOS_VCORE_LEVEL_IDX] =
+ (sw_req >> VCORE_SW_AP_SHIFT) & VCORE_SW_AP_MASK;
+
+ met_vcorefs_src[SRC_CM_MGR_LEVEL_IDX] =
+ (dvfsrc_read(DVFSRC_SW_REQ2) >> EMI_SW_AP2_SHIFT) &
+ EMI_SW_AP2_MASK;
+
+#ifdef CONFIG_MTK_EMI
+ met_vcorefs_src[SRC_TOTAL_EMI_LEVEL_1_IDX] =
+ total_bw_status & 0x1;
+ met_vcorefs_src[SRC_TOTAL_EMI_LEVEL_2_IDX] =
+ (total_bw_status >> 1) & 0x1;
+ met_vcorefs_src[SRC_TOTAL_EMI_RESULT_IDX] =
+ total_bw_last;
+#endif
+ met_vcorefs_src[SRC_QOS_BW_LEVEL1_IDX] =
+ (qos_total_bw >= qos0_thres) ? 1 : 0;
+ met_vcorefs_src[SRC_QOS_BW_LEVEL2_IDX] =
+ (qos_total_bw >= qos1_thres) ? 1 : 0;
+ met_vcorefs_src[SRC_QOS_BW_RESUT_IDX] =
+ qos_total_bw * 100;
+
+ met_vcorefs_src[SRC_SCP_VCORE_LEVEL_IDX] =
+ (dvfsrc_read(DVFSRC_VCORE_REQUEST) >> VCORE_SCP_GEAR_SHIFT) &
+ VCORE_SCP_GEAR_MASK;
+
+ vcorefs_trace_qos();
+
+ return met_vcorefs_src;
+}
+EXPORT_SYMBOL(vcorefs_get_src_req);
diff --git a/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-mt2731.h b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-mt2731.h
new file mode 100644
index 0000000..ff070e9
--- /dev/null
+++ b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-mt2731.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+#ifndef __MTK_DVFSRC_MT2731_H
+#define __MTK_DVFSRC_MT2731_H
+
+#ifdef CONFIG_MTK_PMIC_COMMON
+#include <mach/upmu_hw.h>
+#endif
+
+#ifdef CONFIG_MTK_PMIC_COMMON
+#define PMIC_VCORE_ADDR PMIC_RG_BUCK_VCORE_VOSEL
+#endif
+
+#define VCORE_BASE_UV 500000
+#define VCORE_STEP_UV 6250
+
+#define AUTOK_ENABLE
+
+#define dvfsrc_rmw(offset, val, mask, shift) \
+ dvfsrc_write(offset, (dvfsrc_read(offset) & ~(mask)) \
+ | (val << shift))
+
+/* met profile table index */
+enum met_info_index {
+ INFO_OPP_IDX = 0,
+ INFO_FREQ_IDX,
+ INFO_VCORE_IDX,
+ INFO_SPM_LEVEL_IDX,
+ INFO_MAX,
+};
+
+enum met_src_index {
+ SRC_MD2SPM_IDX = 0,
+ SRC_QOS_EMI_LEVEL_IDX,
+ SRC_QOS_VCORE_LEVEL_IDX,
+ SRC_CM_MGR_LEVEL_IDX,
+ SRC_TOTAL_EMI_LEVEL_1_IDX,
+ SRC_TOTAL_EMI_LEVEL_2_IDX,
+ SRC_TOTAL_EMI_RESULT_IDX,
+ SRC_QOS_BW_LEVEL1_IDX,
+ SRC_QOS_BW_LEVEL2_IDX,
+ SRC_QOS_BW_RESUT_IDX,
+ SRC_SCP_VCORE_LEVEL_IDX,
+ SRC_MAX
+};
+
+extern int commit_data(int type, int data);
+
+#endif /* __MTK_DVFSRC_MT2731_H */
+
+
diff --git a/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-opp-mt2731.c b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-opp-mt2731.c
new file mode 100644
index 0000000..3b91f33
--- /dev/null
+++ b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-opp-mt2731.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+#include <linux/kernel.h>
+#include <mtk_spm_internal.h>
+
+#include "mtk-dvfsrc-opp.h"
+#ifdef CONFIG_MTK_DRAMC
+#include <mtk_dramc.h>
+#endif
+
+int __weak dram_steps_freq(unsigned int step)
+{
+ pr_info("get dram steps_freq fail\n");
+ return -1;
+}
+
+int ddr_level_to_step(int opp)
+{
+ unsigned int step[] = {0, 8, 6, 4, 2, 7};
+ return step[opp];
+}
+
+void dvfsrc_opp_level_mapping(void)
+{
+ int vcore_opp_0_uv, vcore_opp_1_uv;
+
+ set_pwrap_cmd(VCORE_OPP_0, 1);
+ set_pwrap_cmd(VCORE_OPP_1, 0);
+ vcore_opp_0_uv = 800000;
+ vcore_opp_1_uv = 750000;
+ pr_info("%s: FINAL vcore_opp_uv: %d, %d\n",
+ __func__,
+ vcore_opp_0_uv,
+ vcore_opp_1_uv);
+
+ set_vcore_uv_table(VCORE_OPP_0, vcore_opp_0_uv);
+ set_vcore_uv_table(VCORE_OPP_1, vcore_opp_1_uv);
+
+ set_vcore_opp(VCORE_DVFS_OPP_0, VCORE_OPP_1);
+ set_vcore_opp(VCORE_DVFS_OPP_1, VCORE_OPP_0);
+
+ set_ddr_opp(VCORE_DVFS_OPP_0, DDR_OPP_0);
+ set_ddr_opp(VCORE_DVFS_OPP_1, DDR_OPP_0);
+
+}
+
+void dvfsrc_opp_table_init(void)
+{
+ int i;
+ int vcore_opp, ddr_opp;
+
+ for (i = 0; i < VCORE_DVFS_OPP_NUM; i++) {
+ vcore_opp = get_vcore_opp(i);
+ ddr_opp = get_ddr_opp(i);
+
+ if (vcore_opp == VCORE_OPP_UNREQ || ddr_opp == DDR_OPP_UNREQ) {
+ set_opp_table(i, 0, 0);
+ continue;
+ }
+ set_opp_table(i, get_vcore_uv_table(vcore_opp),
+ dram_steps_freq(ddr_level_to_step(ddr_opp)) * 1000);
+ }
+}
+
diff --git a/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-opp-mt2731.h b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-opp-mt2731.h
new file mode 100644
index 0000000..2bfed87
--- /dev/null
+++ b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-opp-mt2731.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+#ifndef __MTK_DVFSRC_OPP_MT2731_H
+#define __MTK_DVFSRC_OPP_MT2731_H
+
+#define DVFSRC_DDR_OPP_DEFAULT_VALUE 16
+#define DVFSRC_VCORE_OPP_DEFAULT_VALUE 16
+#define DVFSRC_VCORE_DVFS_FORCE_OPP_DEFAULT_VALUE 16
+
+
+enum {
+ DVFSRC_DDR_OPP = 0,
+ DVFSRC_VCORE_OPP,
+ DVFSRC_VCORE_DVFS_FORCE_OPP,
+ DVFSRC_VCORE_DVFS_FORCE_OPP_WORKAROUND,
+ DVFSRC_NUM_CLASSES,
+ DVFSRC_UNREQ = 16,
+};
+
+int ddr_level_to_step(int opp);
+
+enum ddr_opp {
+ DDR_OPP_0 = 0,
+ DDR_OPP_NUM,
+ DDR_OPP_UNREQ = DVFSRC_DDR_OPP_DEFAULT_VALUE,
+};
+
+enum vcore_opp {
+ VCORE_OPP_0 = 0,
+ VCORE_OPP_1,
+ VCORE_OPP_NUM,
+ VCORE_OPP_UNREQ = DVFSRC_VCORE_OPP_DEFAULT_VALUE,
+};
+
+enum vcore_dvfs_opp {
+ VCORE_DVFS_OPP_0 = 0,
+ VCORE_DVFS_OPP_1,
+ VCORE_DVFS_OPP_2,
+ VCORE_DVFS_OPP_3,
+ VCORE_DVFS_OPP_NUM,
+ VCORE_DVFS_OPP_UNREQ = DVFSRC_VCORE_DVFS_FORCE_OPP_DEFAULT_VALUE,
+};
+
+#endif /* __MTK_DVFSRC_OPP_MT2731_H */
+
diff --git a/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-opp.c b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-opp.c
new file mode 100644
index 0000000..e7ea6f2
--- /dev/null
+++ b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-opp.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+#include "mtk-dvfsrc.h"
+#include "mtk-dvfsrc-opp.h"
+
+static struct opp_profile opp_table[VCORE_DVFS_OPP_NUM];
+static int vcore_dvfs_to_vcore_opp[VCORE_DVFS_OPP_NUM];
+static int vcore_dvfs_to_ddr_opp[VCORE_DVFS_OPP_NUM];
+static int vcore_uv_table[VCORE_OPP_NUM];
+static int vcore_opp_to_pwrap_cmd[VCORE_OPP_NUM];
+static int ddr_table[DDR_OPP_NUM];
+
+
+/* ToDo: Copy Opp Table to AEE Dump */
+int get_cur_vcore_dvfs_opp(void)
+{
+#if defined(VCOREFS_LEVEL_POSITIVE)
+ int val = __builtin_ffs(spm_get_dvfs_level());
+
+ if (val == 0)
+ return VCORE_DVFS_OPP_NUM;
+ else
+ return val - 1;
+#else
+ return VCORE_DVFS_OPP_NUM - __builtin_ffs(spm_get_dvfs_level());
+#endif
+}
+
+void set_opp_table(int vcore_dvfs_opp, int vcore_uv, int ddr_khz)
+{
+ opp_table[vcore_dvfs_opp].vcore_uv = vcore_uv;
+ opp_table[vcore_dvfs_opp].ddr_khz = ddr_khz;
+}
+
+void set_vcore_opp(int vcore_dvfs_opp, int vcore_opp)
+{
+ vcore_dvfs_to_vcore_opp[vcore_dvfs_opp] = vcore_opp;
+}
+
+int get_vcore_opp(int opp)
+{
+ return vcore_dvfs_to_vcore_opp[opp];
+}
+
+int get_vcore_uv(int opp)
+{
+ return opp_table[opp].vcore_uv;
+}
+
+int get_cur_vcore_opp(void)
+{
+ int idx;
+
+ if (!is_dvfsrc_enabled())
+ return VCORE_OPP_UNREQ;
+
+ idx = get_cur_vcore_dvfs_opp();
+
+ if (idx >= VCORE_DVFS_OPP_NUM)
+ return VCORE_OPP_UNREQ;
+ return vcore_dvfs_to_vcore_opp[idx];
+}
+
+int get_cur_vcore_uv(void)
+{
+ int idx;
+
+ if (!is_dvfsrc_enabled())
+ return 0;
+
+ idx = get_cur_vcore_dvfs_opp();
+
+ if (idx >= VCORE_DVFS_OPP_NUM)
+ return 0;
+ return opp_table[idx].vcore_uv;
+}
+
+void set_ddr_opp(int vcore_dvfs_opp, int ddr_opp)
+{
+ vcore_dvfs_to_ddr_opp[vcore_dvfs_opp] = ddr_opp;
+}
+
+int get_ddr_opp(int opp)
+{
+ return vcore_dvfs_to_ddr_opp[opp];
+}
+
+int get_ddr_khz(int opp)
+{
+ return opp_table[opp].ddr_khz;
+}
+
+int get_cur_ddr_opp(void)
+{
+ int idx;
+
+ if (!is_dvfsrc_enabled())
+ return DDR_OPP_UNREQ;
+
+ idx = get_cur_vcore_dvfs_opp();
+
+ if (idx >= VCORE_DVFS_OPP_NUM)
+ return DDR_OPP_UNREQ;
+ return vcore_dvfs_to_ddr_opp[idx];
+}
+
+int get_cur_ddr_khz(void)
+{
+ int idx;
+
+ if (!is_dvfsrc_enabled())
+ return 0;
+
+ idx = get_cur_vcore_dvfs_opp();
+
+ if (idx >= VCORE_DVFS_OPP_NUM)
+ return 0;
+ return opp_table[idx].ddr_khz;
+}
+
+void set_vcore_uv_table(int vcore_opp, int vcore_uv)
+{
+ spm_dvfs_pwrap_cmd(get_pwrap_cmd(vcore_opp),
+ vcore_uv_to_pmic(vcore_uv));
+ vcore_uv_table[vcore_opp] = vcore_uv;
+}
+
+int get_opp_ddr_freq(int ddr_opp)
+{
+ return ddr_table[ddr_opp];
+}
+
+void set_opp_ddr_freq(int ddr_opp, int ddr_freq)
+{
+ ddr_table[ddr_opp] = ddr_freq;
+}
+
+int get_vcore_uv_table(int vcore_opp)
+{
+ return vcore_uv_table[vcore_opp];
+}
+
+void set_pwrap_cmd(int vcore_opp, int pwrap_cmd)
+{
+ vcore_opp_to_pwrap_cmd[vcore_opp] = pwrap_cmd;
+}
+
+int get_pwrap_cmd(int vcore_opp)
+{
+ return vcore_opp_to_pwrap_cmd[vcore_opp];
+}
diff --git a/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-opp.h b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-opp.h
new file mode 100644
index 0000000..6968194
--- /dev/null
+++ b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-opp.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+#ifndef __MTK_DVFSRC_OPP_H
+#define __MTK_DVFSRC_OPP_H
+
+#if defined(CONFIG_MACH_MT2731)
+#include "mtk-dvfsrc-opp-mt2731.h"
+#endif
+
+struct opp_profile {
+ int vcore_uv;
+ int ddr_khz;
+};
+
+extern int get_cur_vcore_dvfs_opp(void);
+extern void set_opp_table(int vcore_dvfs_opp, int vcore_uv, int ddr_khz);
+
+extern int get_vcore_opp(int opp);
+extern int get_vcore_uv(int opp);
+extern int get_cur_vcore_opp(void);
+extern int get_cur_vcore_uv(void);
+extern void set_vcore_opp(int vcore_dvfs_opp, int vcore_opp);
+
+extern int get_ddr_opp(int opp);
+extern int get_ddr_khz(int opp);
+extern int get_cur_ddr_opp(void);
+extern int get_cur_ddr_khz(void);
+extern void set_ddr_opp(int vcore_dvfs_opp, int ddr_opp);
+
+extern void set_vcore_uv_table(int vcore_opp, int vcore_uv);
+extern int get_vcore_uv_table(int vcore_opp);
+
+extern void set_pwrap_cmd(int vcore_opp, int pwrap_cmd);
+extern int get_pwrap_cmd(int vcore_opp);
+extern int get_opp_ddr_freq(int ddr_opp);
+extern void set_opp_ddr_freq(int ddr_opp, int ddr_freq);
+
+#endif /* __MTK_DVFSRC_OPP_H */
diff --git a/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-sysfs.c b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-sysfs.c
new file mode 100644
index 0000000..7cfa70d
--- /dev/null
+++ b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc-sysfs.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/sysfs.h>
+
+#include "mtk-dvfsrc.h"
+#include "mtk-dvfsrc-opp.h"
+
+__weak void dvfsrc_enable_dvfs_freq_hopping(int gps_on)
+{
+ pr_info("dummy %s(%d)\n", __func__, gps_on);
+}
+
+__weak int dvfsrc_get_dvfs_freq_hopping_status(void)
+{
+ pr_info("dummy %s\n", __func__);
+ return 0;
+}
+/* Enable DVFSRC */
+static ssize_t dvfsrc_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", is_dvfsrc_enabled());
+}
+static ssize_t dvfsrc_enable_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int val = 0;
+
+ if (kstrtoint(buf, 10, &val))
+ return -EINVAL;
+
+ dvfsrc_enable(val);
+
+ return count;
+}
+static DEVICE_ATTR(dvfsrc_enable, 0644,
+ dvfsrc_enable_show, dvfsrc_enable_store);
+
+/* Set DVFSRC RUN FLAG */
+static ssize_t dvfsrc_enable_flag_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%x\n", dvfsrc_flag_get());
+}
+static ssize_t dvfsrc_enable_flag_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int val = 0;
+
+ if (kstrtoint(buf, 16, &val))
+ return -EINVAL;
+
+ dvfsrc_flag_set(val);
+
+ return count;
+}
+
+static DEVICE_ATTR(dvfsrc_enable_flag, 0644,
+ dvfsrc_enable_flag_show, dvfsrc_enable_flag_store);
+
+/* Request DRAM OPP */
+static ssize_t dvfsrc_req_ddr_opp_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int val = 0;
+
+ if (kstrtoint(buf, 10, &val))
+ return -EINVAL;
+
+ dvfsrc_set_ddr_opp(val);
+
+ return count;
+}
+static DEVICE_ATTR(dvfsrc_req_ddr_opp, 0200,
+ NULL, dvfsrc_req_ddr_opp_store);
+
+/* Request Vcore OPP*/
+static ssize_t dvfsrc_req_vcore_opp_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int val = 0;
+
+ if (kstrtoint(buf, 10, &val))
+ return -EINVAL;
+
+ dvfsrc_set_vcore_opp(val);
+
+ return count;
+}
+static DEVICE_ATTR(dvfsrc_req_vcore_opp, 0200,
+ NULL, dvfsrc_req_vcore_opp_store);
+
+/* Set Vcore uv */
+static ssize_t dvfsrc_set_vcore_uv_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int opp = 0, vcore_uv = 0;
+
+ if (sscanf(buf, "%d %d", &opp, &vcore_uv) != 2)
+ return -EINVAL;
+
+ set_vcore_uv_table(opp, vcore_uv);
+ dvfsrc_opp_table_init();
+
+ return count;
+}
+static DEVICE_ATTR(dvfsrc_set_vcore_uv, 0200,
+ NULL, dvfsrc_set_vcore_uv_store);
+
+/* Force VCORE DVFS OPP */
+static ssize_t dvfsrc_force_vcore_dvfs_opp_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int val = 0;
+
+ if (kstrtoint(buf, 10, &val))
+ return -EINVAL;
+
+ dvfsrc_set_vcore_dvfs_force_opp(val);
+
+ return count;
+}
+static DEVICE_ATTR(dvfsrc_force_vcore_dvfs_opp, 0200,
+ NULL, dvfsrc_force_vcore_dvfs_opp_store);
+
+/* Get OPP Table */
+static ssize_t dvfsrc_opp_table_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct dvfsrc *dvfsrc;
+ char *p = buf;
+ char *buff_end = p + PAGE_SIZE;
+ int i;
+
+ dvfsrc = dev_get_drvdata(dev);
+
+ if (!dvfsrc)
+ return sprintf(buf, "Failed to access dvfsrc\n");
+
+ mutex_lock(&dvfsrc->devfreq->lock);
+ for (i = 0; i < VCORE_DVFS_OPP_NUM; i++) {
+ p += snprintf(p, buff_end - p, "[OPP%-2d]: %-8u uv %-8u khz\n",
+ i, get_vcore_uv(i), get_ddr_khz(i));
+ }
+
+ p += snprintf(p, buff_end - p, "\n");
+ mutex_unlock(&dvfsrc->devfreq->lock);
+
+ return p - buf;
+}
+
+static DEVICE_ATTR(dvfsrc_opp_table, 0444, dvfsrc_opp_table_show, NULL);
+
+/* Dump DVFSRC / SPM / PM QoS Register */
+static ssize_t dvfsrc_dump_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char *p = buf;
+
+ p = dvfsrc_dump_reg(p);
+
+ return p - buf;
+}
+
+static DEVICE_ATTR(dvfsrc_dump, 0444, dvfsrc_dump_show, NULL);
+
+
+static ssize_t dvfsrc_freq_hopping_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n",
+ dvfsrc_get_dvfs_freq_hopping_status());
+}
+
+static ssize_t dvfsrc_freq_hopping_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int val = 0;
+
+ if (kstrtoint(buf, 10, &val))
+ return -EINVAL;
+
+ dvfsrc_enable_dvfs_freq_hopping(val);
+
+ return count;
+}
+
+static DEVICE_ATTR(dvfsrc_freq_hopping, 0644,
+ dvfsrc_freq_hopping_show, dvfsrc_freq_hopping_store);
+
+/* Dump DVFSRC latch data */
+static ssize_t dvfsrc_latch_dump_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char *p = buf;
+
+ p = dvfsrc_dump_lacth_reg(p);
+
+ return p - buf;
+}
+
+static DEVICE_ATTR(dvfsrc_latch_dump, 0444, dvfsrc_latch_dump_show, NULL);
+
+/* Force VCORE DVFS OPP for Workaround */
+static ssize_t dvfsrc_force_vcore_dvfs_opp_workaround_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int val = 0;
+
+ if (kstrtoint(buf, 10, &val))
+ return -EINVAL;
+
+ dvfsrc_set_vcore_dvfs_force_workaround_opp();
+
+ return count;
+}
+static DEVICE_ATTR(dvfsrc_force_vcore_dvfs_opp_workaround, 0200,
+ NULL, dvfsrc_force_vcore_dvfs_opp_workaround_store);
+
+static struct attribute *dvfsrc_attrs[] = {
+ &dev_attr_dvfsrc_enable.attr,
+ &dev_attr_dvfsrc_enable_flag.attr,
+ &dev_attr_dvfsrc_req_ddr_opp.attr,
+ &dev_attr_dvfsrc_req_vcore_opp.attr,
+ &dev_attr_dvfsrc_force_vcore_dvfs_opp.attr,
+ &dev_attr_dvfsrc_set_vcore_uv.attr,
+ &dev_attr_dvfsrc_opp_table.attr,
+ &dev_attr_dvfsrc_dump.attr,
+ &dev_attr_dvfsrc_freq_hopping.attr,
+ &dev_attr_dvfsrc_latch_dump.attr,
+ &dev_attr_dvfsrc_force_vcore_dvfs_opp_workaround.attr,
+ NULL,
+};
+
+static struct attribute_group dvfsrc_attr_group = {
+ .name = "dvfsrc",
+ .attrs = dvfsrc_attrs,
+};
+
+int dvfsrc_add_interface(struct device *dev)
+{
+ int r;
+
+ r = sysfs_create_group(power_kobj, &dvfsrc_attr_group);
+ if (r) {
+ pr_info("[SPM] FAILED TO CREATE ");
+ pr_info("/sys/power/dvfsrc(%d)\n", r);
+ }
+ return r;
+}
+
+void dvfsrc_remove_interface(struct device *dev)
+{
+ sysfs_remove_group(power_kobj, &dvfsrc_attr_group);
+}
diff --git a/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc.h b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc.h
new file mode 100644
index 0000000..b35a0e0
--- /dev/null
+++ b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+#ifndef _MTK_DVFSRC_H
+#define _MTK_DVFSRC_H
+
+#include <linux/delay.h>
+#include <linux/devfreq.h>
+#include <linux/io.h>
+
+#if defined(CONFIG_MACH_MT2731)
+#include "mtk-dvfsrc-mt2731.h"
+#endif
+
+#include "mtk-dvfsrc-opp.h"
+
+struct dvfsrc {
+ struct devfreq *devfreq;
+ struct device *dev;
+ bool qos_enabled;
+ bool dvfsrc_enabled;
+ int dvfsrc_flag;
+ void __iomem *regs;
+ void __iomem *sram_regs;
+ bool opp_forced;
+ char force_start[20];
+ char force_end[20];
+ int (*suspend)(struct dvfsrc *dvfsrc_dev);
+ int (*resume)(struct dvfsrc *dvfsrc_dev);
+};
+
+#define DVFSRC_TIMEOUT 1000
+
+/* PMIC */
+#define vcore_pmic_to_uv(pmic) \
+ (((pmic) * VCORE_STEP_UV) + VCORE_BASE_UV)
+#define vcore_uv_to_pmic(uv) /* pmic >= uv */ \
+ ((((uv) - VCORE_BASE_UV) + (VCORE_STEP_UV - 1)) / VCORE_STEP_UV)
+
+#define dvfsrc_wait_for_completion(condition, timeout) \
+({ \
+ int ret = 0; \
+ if (is_dvfsrc_enabled()) \
+ ret = 1; \
+ while (!(condition) && ret > 0) { \
+ if (ret++ >= timeout) \
+ ret = -EBUSY; \
+ udelay(1); \
+ } \
+ ret; \
+})
+
+extern int is_qos_enabled(void);
+extern int is_dvfsrc_enabled(void);
+extern int is_opp_forced(void);
+extern int dvfsrc_get_emi_bw(int type);
+extern int get_vcore_dvfs_level(void);
+extern void mtk_spmfw_init(int dvfsrc_en, int skip_check);
+extern void dvfsrc_enable(int dvfsrc_en);
+extern void dvfsrc_flag_set(int flag);
+extern int dvfsrc_flag_get(void);
+extern char *dvfsrc_dump_reg(char *ptr);
+extern char *dvfsrc_dump_lacth_reg(char *ptr);
+extern u32 dvfsrc_read(u32 offset);
+extern void dvfsrc_write(u32 offset, u32 val);
+extern u32 dvfsrc_sram_read(u32 offset);
+extern void dvfsrc_sram_write(u32 offset, u32 val);
+extern void dvfsrc_opp_table_init(void);
+extern void dvfsrc_sram_reg_init(void);
+
+extern int dvfsrc_add_interface(struct device *dev);
+extern void dvfsrc_remove_interface(struct device *dev);
+extern void dvfsrc_opp_level_mapping(void);
+extern void dvfsrc_sspm_ipi_init(int dvfsrc_en);
+extern void get_opp_info(char *p);
+extern void get_dvfsrc_reg(char *p);
+extern void get_dvfsrc_record(char *p);
+extern void get_spm_reg(char *p);
+extern void spm_dvfs_pwrap_cmd(int pwrap_cmd, int pwrap_vcore);
+extern int dvfsrc_platform_init(struct dvfsrc *dvfsrc);
+extern u32 spm_get_dvfs_level(void);
+extern u32 spm_get_pcm_reg9_data(void);
+
+/* met profile function */
+extern int vcorefs_get_opp_info_num(void);
+extern char **vcorefs_get_opp_info_name(void);
+extern unsigned int *vcorefs_get_opp_info(void);
+extern int vcorefs_get_src_req_num(void);
+extern char **vcorefs_get_src_req_name(void);
+extern unsigned int *vcorefs_get_src_req(void);
+extern u32 vcorefs_get_md_scenario(void);
+
+/* DVFSRC Set APIs */
+extern void dvfsrc_set_ddr_opp(int level);
+extern void dvfsrc_set_vcore_opp(int level);
+extern void dvfsrc_set_vcore_dvfs_force_opp(int level);
+extern void dvfsrc_set_vcore_dvfs_force_workaround_opp(void);
+
+/*DVFSRC Get APIs */
+extern int dvfsrc_get_reguest(unsigned int id);
+
+#endif /* __MTK_DVFSRC_H */
+
diff --git a/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc_reg.h b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc_reg.h
new file mode 100644
index 0000000..7f6e174
--- /dev/null
+++ b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc_reg.h
@@ -0,0 +1,1266 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+#ifndef __MTK_DVFSRC_REG_H
+#define __MTK_DVFSRC_REG_H
+
+/**************************************
+ * Define and Declare
+ **************************************/
+
+/* it from dvfsrc_par.py */
+/* #define DVFSRC_APB_BASE (0x10012000) */
+#define DVFSRC_BASIC_CONTROL (0x0)
+#define DVFSRC_SW_REQ (0x4)
+#define DVFSRC_SW_REQ2 (0x8)
+#define DVFSRC_EMI_REQUEST (0xC)
+#define DVFSRC_EMI_REQUEST2 (0x10)
+#define DVFSRC_EMI_REQUEST3 (0x14)
+#define DVFSRC_EMI_HRT (0x18)
+#define DVFSRC_EMI_HRT2 (0x1C)
+#define DVFSRC_EMI_HRT3 (0x20)
+#define DVFSRC_EMI_QOS0 (0x24)
+#define DVFSRC_EMI_QOS1 (0x28)
+#define DVFSRC_EMI_QOS2 (0x2C)
+#define DVFSRC_EMI_MD2SPM0 (0x30)
+#define DVFSRC_EMI_MD2SPM1 (0x34)
+#define DVFSRC_EMI_MD2SPM2 (0x38)
+#define DVFSRC_EMI_MD2SPM0_T (0x3C)
+#define DVFSRC_EMI_MD2SPM1_T (0x40)
+#define DVFSRC_EMI_MD2SPM2_T (0x44)
+#define DVFSRC_VCORE_REQUEST (0x48)
+#define DVFSRC_VCORE_REQUEST2 (0x4C)
+#define DVFSRC_VCORE_HRT (0x50)
+#define DVFSRC_VCORE_HRT2 (0x54)
+#define DVFSRC_VCORE_HRT3 (0x58)
+#define DVFSRC_VCORE_QOS0 (0x5C)
+#define DVFSRC_VCORE_QOS1 (0x60)
+#define DVFSRC_VCORE_QOS2 (0x64)
+#define DVFSRC_VCORE_MD2SPM0 (0x68)
+#define DVFSRC_VCORE_MD2SPM1 (0x6C)
+#define DVFSRC_VCORE_MD2SPM2 (0x70)
+#define DVFSRC_VCORE_MD2SPM0_T (0x74)
+#define DVFSRC_VCORE_MD2SPM1_T (0x78)
+#define DVFSRC_VCORE_MD2SPM2_T (0x7C)
+#define DVFSRC_MD_REQUEST (0x80)
+#define DVFSRC_MD_SW_CONTROL (0x84)
+#define DVFSRC_MD_VMODEM_REMAP (0x88)
+#define DVFSRC_MD_VMD_REMAP (0x8C)
+#define DVFSRC_MD_VSRAM_REMAP (0x90)
+#define DVFSRC_HALT_SW_CONTROL (0x94)
+#define DVFSRC_INT (0x98)
+#define DVFSRC_INT_EN (0x9C)
+#define DVFSRC_INT_CLR (0xA0)
+#define DVFSRC_BW_MON_WINDOW (0xA4)
+#define DVFSRC_BW_MON_THRES_1 (0xA8)
+#define DVFSRC_BW_MON_THRES_2 (0xAC)
+#define DVFSRC_MD_TURBO (0xB0)
+#define DVFSRC_DEBOUNCE_FOUR (0xD0)
+#define DVFSRC_DEBOUNCE_RISE_FALL (0xD4)
+#define DVFSRC_TIMEOUT_NEXTREQ (0xD8)
+#define DVFSRC_LEVEL (0xDC)
+#define DVFSRC_LEVEL_LABEL_0_1 (0xE0)
+#define DVFSRC_LEVEL_LABEL_2_3 (0xE4)
+#define DVFSRC_LEVEL_LABEL_4_5 (0xE8)
+#define DVFSRC_LEVEL_LABEL_6_7 (0xEC)
+#define DVFSRC_LEVEL_LABEL_8_9 (0xF0)
+#define DVFSRC_LEVEL_LABEL_10_11 (0xF4)
+#define DVFSRC_LEVEL_LABEL_12_13 (0xF8)
+#define DVFSRC_LEVEL_LABEL_14_15 (0xFC)
+#define DVFSRC_MM_BW_0 (0x100)
+#define DVFSRC_MM_BW_1 (0x104)
+#define DVFSRC_MM_BW_2 (0x108)
+#define DVFSRC_MM_BW_3 (0x10C)
+#define DVFSRC_MM_BW_4 (0x110)
+#define DVFSRC_MM_BW_5 (0x114)
+#define DVFSRC_MM_BW_6 (0x118)
+#define DVFSRC_MM_BW_7 (0x11C)
+#define DVFSRC_MM_BW_8 (0x120)
+#define DVFSRC_MM_BW_9 (0x124)
+#define DVFSRC_MM_BW_10 (0x128)
+#define DVFSRC_MM_BW_11 (0x12C)
+#define DVFSRC_MM_BW_12 (0x130)
+#define DVFSRC_MM_BW_13 (0x134)
+#define DVFSRC_MM_BW_14 (0x138)
+#define DVFSRC_MM_BW_15 (0x13C)
+#define DVFSRC_MD_BW_0 (0x140)
+#define DVFSRC_MD_BW_1 (0x144)
+#define DVFSRC_MD_BW_2 (0x148)
+#define DVFSRC_MD_BW_3 (0x14C)
+#define DVFSRC_MD_BW_4 (0x150)
+#define DVFSRC_MD_BW_5 (0x154)
+#define DVFSRC_MD_BW_6 (0x158)
+#define DVFSRC_MD_BW_7 (0x15C)
+#define DVFSRC_SW_BW_0 (0x160)
+#define DVFSRC_SW_BW_1 (0x164)
+#define DVFSRC_SW_BW_2 (0x168)
+#define DVFSRC_SW_BW_3 (0x16C)
+#define DVFSRC_SW_BW_4 (0x170)
+#define DVFSRC_QOS_EN (0x180)
+#define DVFSRC_ISP_HRT (0x190)
+#define DVFSRC_FORCE (0x300)
+#define DVFSRC_SEC_SW_REQ (0x304)
+#define DVFSRC_LAST (0x308)
+#define DVFSRC_LAST_L (0x30C)
+#define DVFSRC_MD_SCENARIO (0x310)
+#define DVFSRC_RECORD_0_0 (0x400)
+#define DVFSRC_RECORD_0_1 (0x404)
+#define DVFSRC_RECORD_0_2 (0x408)
+#define DVFSRC_RECORD_1_0 (0x40C)
+#define DVFSRC_RECORD_1_1 (0x410)
+#define DVFSRC_RECORD_1_2 (0x414)
+#define DVFSRC_RECORD_2_0 (0x418)
+#define DVFSRC_RECORD_2_1 (0x41C)
+#define DVFSRC_RECORD_2_2 (0x420)
+#define DVFSRC_RECORD_3_0 (0x424)
+#define DVFSRC_RECORD_3_1 (0x428)
+#define DVFSRC_RECORD_3_2 (0x42C)
+#define DVFSRC_RECORD_4_0 (0x430)
+#define DVFSRC_RECORD_4_1 (0x434)
+#define DVFSRC_RECORD_4_2 (0x438)
+#define DVFSRC_RECORD_5_0 (0x43C)
+#define DVFSRC_RECORD_5_1 (0x440)
+#define DVFSRC_RECORD_5_2 (0x444)
+#define DVFSRC_RECORD_6_0 (0x448)
+#define DVFSRC_RECORD_6_1 (0x44C)
+#define DVFSRC_RECORD_6_2 (0x450)
+#define DVFSRC_RECORD_7_0 (0x454)
+#define DVFSRC_RECORD_7_1 (0x458)
+#define DVFSRC_RECORD_7_2 (0x45C)
+#define DVFSRC_RECORD_0_L_0 (0x460)
+#define DVFSRC_RECORD_0_L_1 (0x464)
+#define DVFSRC_RECORD_0_L_2 (0x468)
+#define DVFSRC_RECORD_1_L_0 (0x46C)
+#define DVFSRC_RECORD_1_L_1 (0x470)
+#define DVFSRC_RECORD_1_L_2 (0x474)
+#define DVFSRC_RECORD_2_L_0 (0x478)
+#define DVFSRC_RECORD_2_L_1 (0x47C)
+#define DVFSRC_RECORD_2_L_2 (0x480)
+#define DVFSRC_RECORD_3_L_0 (0x484)
+#define DVFSRC_RECORD_3_L_1 (0x488)
+#define DVFSRC_RECORD_3_L_2 (0x48C)
+#define DVFSRC_RECORD_4_L_0 (0x490)
+#define DVFSRC_RECORD_4_L_1 (0x494)
+#define DVFSRC_RECORD_4_L_2 (0x498)
+#define DVFSRC_RECORD_5_L_0 (0x49C)
+#define DVFSRC_RECORD_5_L_1 (0x4A0)
+#define DVFSRC_RECORD_5_L_2 (0x4A4)
+#define DVFSRC_RECORD_6_L_0 (0x4A8)
+#define DVFSRC_RECORD_6_L_1 (0x4AC)
+#define DVFSRC_RECORD_6_L_2 (0x4B0)
+#define DVFSRC_RECORD_7_L_0 (0x4B4)
+#define DVFSRC_RECORD_7_L_1 (0x4B8)
+#define DVFSRC_RECORD_7_L_2 (0x4BC)
+#define DVFSRC_RECORD_MD_0 (0x4C0)
+#define DVFSRC_RECORD_MD_1 (0x4C4)
+#define DVFSRC_RECORD_MD_2 (0x4C8)
+#define DVFSRC_RECORD_MD_3 (0x4CC)
+#define DVFSRC_RECORD_MD_4 (0x4D0)
+#define DVFSRC_RECORD_MD_5 (0x4D4)
+#define DVFSRC_RECORD_MD_6 (0x4D8)
+#define DVFSRC_RECORD_MD_7 (0x4DC)
+#define DVFSRC_RECORD_COUNT (0x4F0)
+#define DVFSRC_RSRV_0 (0x600)
+#define DVFSRC_RSRV_1 (0x604)
+#define DVFSRC_RSRV_2 (0x608)
+#define DVFSRC_RSRV_3 (0x60C)
+#define DVFSRC_RSRV_4 (0x610)
+#define DVFSRC_RSRV_5 (0x614)
+
+/* DVFSRC_BASIC_CONTROL(0x10012000 + 0x0) */
+#define TARGET_LEVEL_LOCK_SHIFT 16
+#define TARGET_LEVEL_LOCK_MASK 0xffff0000
+#define FORCE_EN_TAR_SHIFT 15
+#define FORCE_EN_TAR_MASK 0x8000
+#define FORCE_EN_CUR_SHIFT 14
+#define FORCE_EN_CUR_MASK 0x4000
+#define ABORT_EN_SHIFT 13
+#define ABORT_EN_MASK 0x2000
+#define CLEAR_HALT_TIMEOUT_SHIFT 12
+#define CLEAR_HALT_TIMEOUT_MASK 0x1000
+#define HALT_TIMEOUT_EN_SHIFT 11
+#define HALT_TIMEOUT_EN_MASK 0x800
+#define READY_TEST_MODE_SHIFT 10
+#define READY_TEST_MODE_MASK 0x400
+#define LOCK_HIGH_ENABLE_SHIFT 9
+#define LOCK_HIGH_ENABLE_MASK 0x200
+#define DVFSRC_OUT_EN_SHIFT 8
+#define DVFSRC_OUT_EN_MASK 0x100
+#define RG_SW_CLR_REQ_SHIFT 7
+#define RG_SW_CLR_REQ_MASK 0x80
+#define MDSRCCLK_CHECK_SHIFT 6
+#define MDSRCCLK_CHECK_MASK 0x40
+#define RG_COUNTER_SEL_SHIFT 4
+#define RG_COUNTER_SEL_MASK 0x30
+#define DVFS_DEBUG_SW_RST_SHIFT 3
+#define DVFS_DEBUG_SW_RST_MASK 0x8
+#define RG_FREEZE_DEBUG_RECORD_SHIFT 2
+#define RG_FREEZE_DEBUG_RECORD_MASK 0x4
+#define DEBUG_EN_SHIFT 1
+#define DEBUG_EN_MASK 0x2
+#define DVFSRC_EN_SHIFT 0
+#define DVFSRC_EN_MASK 0x1
+
+/* DVFSRC_SW_REQ(0x10012000 + 0x4) */
+#define VCORE_SW_AP_SHIFT 2
+#define VCORE_SW_AP_MASK 0xc
+#define EMI_SW_AP_SHIFT 0
+#define EMI_SW_AP_MASK 0x3
+
+/* DVFSRC_SW_REQ2(0x10012000 + 0x8) */
+#define VCORE_SW_AP2_SHIFT 2
+#define VCORE_SW_AP2_MASK 0xc
+#define EMI_SW_AP2_SHIFT 0
+#define EMI_SW_AP2_MASK 0x3
+
+/* DVFSRC_EMI_REQUEST(0x10012000 + 0xC) */
+#define EMI_EX_GEAR_SHIFT 28
+#define EMI_EX_GEAR_MASK 0x30000000
+#define EMI_CONN_GEAR_SHIFT 26
+#define EMI_CONN_GEAR_MASK 0xc000000
+#define EMI_MD2SPM_GEAR2_SHIFT 20
+#define EMI_MD2SPM_GEAR2_MASK 0x300000
+#define EMI_MD2SPM_GEAR1_SHIFT 18
+#define EMI_MD2SPM_GEAR1_MASK 0xc0000
+#define EMI_MD2SPM_GEAR0_SHIFT 16
+#define EMI_MD2SPM_GEAR0_MASK 0x30000
+#define EMI_MD_LATENCY_GEAR1_SHIFT 10
+#define EMI_MD_LATENCY_GEAR1_MASK 0xc00
+#define EMI_MD_LATENCY_GEAR0_SHIFT 8
+#define EMI_MD_LATENCY_GEAR0_MASK 0x300
+#define EMI_TOTAL_BW2_GEAR1_SHIFT 6
+#define EMI_TOTAL_BW2_GEAR1_MASK 0xc0
+#define EMI_TOTAL_BW2_GEAR0_SHIFT 4
+#define EMI_TOTAL_BW2_GEAR0_MASK 0x30
+#define EMI_TOTAL_BW_GEAR1_SHIFT 2
+#define EMI_TOTAL_BW_GEAR1_MASK 0xc
+#define EMI_TOTAL_BW_GEAR0_SHIFT 0
+#define EMI_TOTAL_BW_GEAR0_MASK 0x3
+
+/* DVFSRC_EMI_REQUEST2(0x10012000 + 0x10) */
+#define EMI_RSRV_BW2_GEAR1_SHIFT 14
+#define EMI_RSRV_BW2_GEAR1_MASK 0xc000
+#define EMI_RSRV_BW2_GEAR0_SHIFT 12
+#define EMI_RSRV_BW2_GEAR0_MASK 0x3000
+#define EMI_RSRV_BW_GEAR1_SHIFT 10
+#define EMI_RSRV_BW_GEAR1_MASK 0xc00
+#define EMI_RSRV_BW_GEAR0_SHIFT 8
+#define EMI_RSRV_BW_GEAR0_MASK 0x300
+#define EMI_GPU_BW_GEAR1_SHIFT 6
+#define EMI_GPU_BW_GEAR1_MASK 0xc0
+#define EMI_GPU_BW_GEAR0_SHIFT 4
+#define EMI_GPU_BW_GEAR0_MASK 0x30
+#define EMI_CPU_BW_GEAR1_SHIFT 2
+#define EMI_CPU_BW_GEAR1_MASK 0xc
+#define EMI_CPU_BW_GEAR0_SHIFT 0
+#define EMI_CPU_BW_GEAR0_MASK 0x3
+
+/* DVFSRC_EMI_REQUEST3(0x10012000 + 0x14) */
+#define EMI_QOS_GEAR2_SHIFT 28
+#define EMI_QOS_GEAR2_MASK 0x30000000
+#define EMI_QOS_GEAR1_SHIFT 26
+#define EMI_QOS_GEAR1_MASK 0xc000000
+#define EMI_QOS_GEAR0_SHIFT 24
+#define EMI_QOS_GEAR0_MASK 0x3000000
+#define EMI_HRT3_GEAR2_SHIFT 20
+#define EMI_HRT3_GEAR2_MASK 0x300000
+#define EMI_HRT3_GEAR1_SHIFT 18
+#define EMI_HRT3_GEAR1_MASK 0xc0000
+#define EMI_HRT3_GEAR0_SHIFT 16
+#define EMI_HRT3_GEAR0_MASK 0x30000
+#define EMI_HRT2_GEAR2_SHIFT 12
+#define EMI_HRT2_GEAR2_MASK 0x3000
+#define EMI_HRT2_GEAR1_SHIFT 10
+#define EMI_HRT2_GEAR1_MASK 0xc00
+#define EMI_HRT2_GEAR0_SHIFT 8
+#define EMI_HRT2_GEAR0_MASK 0x300
+#define EMI_HRT_GEAR2_SHIFT 4
+#define EMI_HRT_GEAR2_MASK 0x30
+#define EMI_HRT_GEAR1_SHIFT 2
+#define EMI_HRT_GEAR1_MASK 0xc
+#define EMI_HRT_GEAR0_SHIFT 0
+#define EMI_HRT_GEAR0_MASK 0x3
+
+/* DVFSRC_EMI_HRT(0x10012000 + 0x18) */
+#define EMI_HRT_THRESHOLD2_SHIFT 16
+#define EMI_HRT_THRESHOLD2_MASK 0xff0000
+#define EMI_HRT_THRESHOLD1_SHIFT 8
+#define EMI_HRT_THRESHOLD1_MASK 0xff00
+#define EMI_HRT_THRESHOLD0_SHIFT 0
+#define EMI_HRT_THRESHOLD0_MASK 0xff
+
+/* DVFSRC_EMI_HRT2(0x10012000 + 0x1C) */
+#define EMI_HRT2_THRESHOLD2_SHIFT 16
+#define EMI_HRT2_THRESHOLD2_MASK 0xff0000
+#define EMI_HRT2_THRESHOLD1_SHIFT 8
+#define EMI_HRT2_THRESHOLD1_MASK 0xff00
+#define EMI_HRT2_THRESHOLD0_SHIFT 0
+#define EMI_HRT2_THRESHOLD0_MASK 0xff
+
+/* DVFSRC_EMI_HRT3(0x10012000 + 0x20) */
+#define EMI_HRT3_THRESHOLD2_SHIFT 16
+#define EMI_HRT3_THRESHOLD2_MASK 0xff0000
+#define EMI_HRT3_THRESHOLD1_SHIFT 8
+#define EMI_HRT3_THRESHOLD1_MASK 0xff00
+#define EMI_HRT3_THRESHOLD0_SHIFT 0
+#define EMI_HRT3_THRESHOLD0_MASK 0xff
+
+/* DVFSRC_EMI_QOS0(0x10012000 + 0x24) */
+#define EMI_QOS_THRESHOLD0_SHIFT 0
+#define EMI_QOS_THRESHOLD0_MASK 0x1fff
+
+/* DVFSRC_EMI_QOS1(0x10012000 + 0x28) */
+#define EMI_QOS_THRESHOLD1_SHIFT 0
+#define EMI_QOS_THRESHOLD1_MASK 0x1fff
+
+/* DVFSRC_EMI_QOS2(0x10012000 + 0x2C) */
+#define EMI_QOS_THRESHOLD2_SHIFT 0
+#define EMI_QOS_THRESHOLD2_MASK 0x1fff
+
+/* DVFSRC_EMI_MD2SPM0(0x10012000 + 0x30) */
+#define EMI_MD2SPM_MASK0_SHIFT 0
+#define EMI_MD2SPM_MASK0_MASK 0xffffffff
+
+/* DVFSRC_EMI_MD2SPM1(0x10012000 + 0x34) */
+#define EMI_MD2SPM_MASK1_SHIFT 0
+#define EMI_MD2SPM_MASK1_MASK 0xffffffff
+
+/* DVFSRC_EMI_MD2SPM2(0x10012000 + 0x38) */
+#define EMI_MD2SPM_MASK2_SHIFT 0
+#define EMI_MD2SPM_MASK2_MASK 0xffffffff
+
+/* DVFSRC_EMI_MD2SPM0_T(0x10012000 + 0x3C) */
+#define EMI_MD2SPM_MASK0_T_SHIFT 0
+#define EMI_MD2SPM_MASK0_T_MASK 0xffffffff
+
+/* DVFSRC_EMI_MD2SPM1_T(0x10012000 + 0x40) */
+#define EMI_MD2SPM_MASK1_T_SHIFT 0
+#define EMI_MD2SPM_MASK1_T_MASK 0xffffffff
+
+/* DVFSRC_EMI_MD2SPM2_T(0x10012000 + 0x44) */
+#define EMI_MD2SPM_MASK2_T_SHIFT 0
+#define EMI_MD2SPM_MASK2_T_MASK 0xffffffff
+
+/* DVFSRC_VCORE_REQUEST(0x10012000 + 0x48) */
+#define VCORE_SCP_GEAR_SHIFT 30
+#define VCORE_SCP_GEAR_MASK 0xc0000000
+#define VCORE_EX_GEAR_SHIFT 28
+#define VCORE_EX_GEAR_MASK 0x30000000
+#define VCORE_CONN_GEAR_SHIFT 26
+#define VCORE_CONN_GEAR_MASK 0xc000000
+#define VCORE_MD2SPM_GEAR2_SHIFT 20
+#define VCORE_MD2SPM_GEAR2_MASK 0x300000
+#define VCORE_MD2SPM_GEAR1_SHIFT 18
+#define VCORE_MD2SPM_GEAR1_MASK 0xc0000
+#define VCORE_MD2SPM_GEAR0_SHIFT 16
+#define VCORE_MD2SPM_GEAR0_MASK 0x30000
+
+/* DVFSRC_VCORE_REQUEST2(0x10012000 + 0x4C) */
+#define VCORE_QOS_GEAR2_SHIFT 28
+#define VCORE_QOS_GEAR2_MASK 0x30000000
+#define VCORE_QOS_GEAR1_SHIFT 26
+#define VCORE_QOS_GEAR1_MASK 0xc000000
+#define VCORE_QOS_GEAR0_SHIFT 24
+#define VCORE_QOS_GEAR0_MASK 0x3000000
+#define VCORE_HRT3_GEAR2_SHIFT 20
+#define VCORE_HRT3_GEAR2_MASK 0x300000
+#define VCORE_HRT3_GEAR1_SHIFT 18
+#define VCORE_HRT3_GEAR1_MASK 0xc0000
+#define VCORE_HRT3_GEAR0_SHIFT 16
+#define VCORE_HRT3_GEAR0_MASK 0x30000
+#define VCORE_HRT2_GEAR2_SHIFT 12
+#define VCORE_HRT2_GEAR2_MASK 0x3000
+#define VCORE_HRT2_GEAR1_SHIFT 10
+#define VCORE_HRT2_GEAR1_MASK 0xc00
+#define VCORE_HRT2_GEAR0_SHIFT 8
+#define VCORE_HRT2_GEAR0_MASK 0x300
+#define VCORE_HRT_GEAR2_SHIFT 4
+#define VCORE_HRT_GEAR2_MASK 0x30
+#define VCORE_HRT_GEAR1_SHIFT 2
+#define VCORE_HRT_GEAR1_MASK 0xc
+#define VCORE_HRT_GEAR0_SHIFT 0
+#define VCORE_HRT_GEAR0_MASK 0x3
+
+/* DVFSRC_VCORE_HRT(0x10012000 + 0x50) */
+#define VCORE_HRT_THRESHOLD2_SHIFT 16
+#define VCORE_HRT_THRESHOLD2_MASK 0xff0000
+#define VCORE_HRT_THRESHOLD1_SHIFT 8
+#define VCORE_HRT_THRESHOLD1_MASK 0xff00
+#define VCORE_HRT_THRESHOLD0_SHIFT 0
+#define VCORE_HRT_THRESHOLD0_MASK 0xff
+
+/* DVFSRC_VCORE_HRT2(0x10012000 + 0x54) */
+#define VCORE_HRT2_THRESHOLD2_SHIFT 16
+#define VCORE_HRT2_THRESHOLD2_MASK 0xff0000
+#define VCORE_HRT2_THRESHOLD1_SHIFT 8
+#define VCORE_HRT2_THRESHOLD1_MASK 0xff00
+#define VCORE_HRT2_THRESHOLD0_SHIFT 0
+#define VCORE_HRT2_THRESHOLD0_MASK 0xff
+
+/* DVFSRC_VCORE_HRT3(0x10012000 + 0x58) */
+#define VCORE_HRT3_THRESHOLD2_SHIFT 16
+#define VCORE_HRT3_THRESHOLD2_MASK 0xff0000
+#define VCORE_HRT3_THRESHOLD1_SHIFT 8
+#define VCORE_HRT3_THRESHOLD1_MASK 0xff00
+#define VCORE_HRT3_THRESHOLD0_SHIFT 0
+#define VCORE_HRT3_THRESHOLD0_MASK 0xff
+
+/* DVFSRC_VCORE_QOS0(0x10012000 + 0x5C) */
+#define VCORE_QOS_THRESHOLD0_SHIFT 0
+#define VCORE_QOS_THRESHOLD0_MASK 0x1fff
+
+/* DVFSRC_VCORE_QOS1(0x10012000 + 0x60) */
+#define VCORE_QOS_THRESHOLD1_SHIFT 0
+#define VCORE_QOS_THRESHOLD1_MASK 0x1fff
+
+/* DVFSRC_VCORE_QOS2(0x10012000 + 0x64) */
+#define VCORE_QOS_THRESHOLD2_SHIFT 0
+#define VCORE_QOS_THRESHOLD2_MASK 0x1fff
+
+/* DVFSRC_VCORE_MD2SPM0(0x10012000 + 0x68) */
+#define VCORE_MD2SPM_MASK0_SHIFT 0
+#define VCORE_MD2SPM_MASK0_MASK 0xffffffff
+
+/* DVFSRC_VCORE_MD2SPM1(0x10012000 + 0x6C) */
+#define VCORE_MD2SPM_MASK1_SHIFT 0
+#define VCORE_MD2SPM_MASK1_MASK 0xffffffff
+
+/* DVFSRC_VCORE_MD2SPM2(0x10012000 + 0x70) */
+#define VCORE_MD2SPM_MASK2_SHIFT 0
+#define VCORE_MD2SPM_MASK2_MASK 0xffffffff
+
+/* DVFSRC_VCORE_MD2SPM0_T(0x10012000 + 0x74) */
+#define VCORE_MD2SPM_MASK0_T_SHIFT 0
+#define VCORE_MD2SPM_MASK0_T_MASK 0xffffffff
+
+/* DVFSRC_VCORE_MD2SPM1_T(0x10012000 + 0x78) */
+#define VCORE_MD2SPM_MASK1_T_SHIFT 0
+#define VCORE_MD2SPM_MASK1_T_MASK 0xffffffff
+
+/* DVFSRC_VCORE_MD2SPM2_T(0x10012000 + 0x7C) */
+#define VCORE_MD2SPM_MASK2_T_SHIFT 0
+#define VCORE_MD2SPM_MASK2_T_MASK 0xffffffff
+
+/* DVFSRC_MD_REQUEST(0x10012000 + 0x80) */
+#define MD_GEAR_SW_REQUEST_SHIFT 0
+#define MD_GEAR_SW_REQUEST_MASK 0x1ff
+
+/* DVFSRC_MD_SW_CONTROL(0x10012000 + 0x84) */
+#define MD_SRCCLKEN_GEAR_MASK_B_SHIFT 29
+#define MD_SRCCLKEN_GEAR_MASK_B_MASK 0x20000000
+#define MD_GEAR_VAL_SAMPLE_SWMODE_SHIFT 20
+#define MD_GEAR_VAL_SAMPLE_SWMODE_MASK 0x1ff00000
+#define MD_GEAR_VAL_SWMODE_SHIFT 8
+#define MD_GEAR_VAL_SWMODE_MASK 0x1ff00
+#define MD_GEAR_RDY_SWMODE_SHIFT 6
+#define MD_GEAR_RDY_SWMODE_MASK 0x40
+#define MD_GEAR_REQ_SWMODE_SHIFT 5
+#define MD_GEAR_REQ_SWMODE_MASK 0x20
+#define MD_GEAR_VAL_SAMPLE_SWMODE_EN_SHIFT 4
+#define MD_GEAR_VAL_SAMPLE_SWMODE_EN_MASK 0x10
+#define MD_GEAR_VAL_SWMODE_EN_SHIFT 3
+#define MD_GEAR_VAL_SWMODE_EN_MASK 0x8
+#define MD_GEAR_RDY_SWMODE_EN_SHIFT 1
+#define MD_GEAR_RDY_SWMODE_EN_MASK 0x2
+#define MD_GEAR_REQ_SWMODE_EN_SHIFT 0
+#define MD_GEAR_REQ_SWMODE_EN_MASK 0x1
+
+/* DVFSRC_MD_VMODEM_REMAP(0x10012000 + 0x88) */
+#define VMODEM_REMAP_EN_SHIFT 31
+#define VMODEM_REMAP_EN_MASK 0x80000000
+#define VMODEM_REMAP_7_SHIFT 28
+#define VMODEM_REMAP_7_MASK 0x70000000
+#define VMODEM_REMAP_6_SHIFT 24
+#define VMODEM_REMAP_6_MASK 0x7000000
+#define VMODEM_REMAP_5_SHIFT 20
+#define VMODEM_REMAP_5_MASK 0x700000
+#define VMODEM_REMAP_4_SHIFT 16
+#define VMODEM_REMAP_4_MASK 0x70000
+#define VMODEM_REMAP_3_SHIFT 12
+#define VMODEM_REMAP_3_MASK 0x7000
+#define VMODEM_REMAP_2_SHIFT 8
+#define VMODEM_REMAP_2_MASK 0x700
+#define VMODEM_REMAP_1_SHIFT 4
+#define VMODEM_REMAP_1_MASK 0x70
+#define VMODEM_REMAP_0_SHIFT 0
+#define VMODEM_REMAP_0_MASK 0x7
+
+/* DVFSRC_MD_VMD_REMAP(0x10012000 + 0x8C) */
+#define VMD_REMAP_EN_SHIFT 31
+#define VMD_REMAP_EN_MASK 0x80000000
+#define VMD_REMAP_7_SHIFT 28
+#define VMD_REMAP_7_MASK 0x70000000
+#define VMD_REMAP_6_SHIFT 24
+#define VMD_REMAP_6_MASK 0x7000000
+#define VMD_REMAP_5_SHIFT 20
+#define VMD_REMAP_5_MASK 0x700000
+#define VMD_REMAP_4_SHIFT 16
+#define VMD_REMAP_4_MASK 0x70000
+#define VMD_REMAP_3_SHIFT 12
+#define VMD_REMAP_3_MASK 0x7000
+#define VMD_REMAP_2_SHIFT 8
+#define VMD_REMAP_2_MASK 0x700
+#define VMD_REMAP_1_SHIFT 4
+#define VMD_REMAP_1_MASK 0x70
+#define VMD_REMAP_0_SHIFT 0
+#define VMD_REMAP_0_MASK 0x7
+
+/* DVFSRC_MD_VSRAM_REMAP(0x10012000 + 0x90) */
+#define VSRAM_REMAP_EN_SHIFT 31
+#define VSRAM_REMAP_EN_MASK 0x80000000
+#define VSRAM_REMAP_7_SHIFT 28
+#define VSRAM_REMAP_7_MASK 0x70000000
+#define VSRAM_REMAP_6_SHIFT 24
+#define VSRAM_REMAP_6_MASK 0x7000000
+#define VSRAM_REMAP_5_SHIFT 20
+#define VSRAM_REMAP_5_MASK 0x700000
+#define VSRAM_REMAP_4_SHIFT 16
+#define VSRAM_REMAP_4_MASK 0x70000
+#define VSRAM_REMAP_3_SHIFT 12
+#define VSRAM_REMAP_3_MASK 0x7000
+#define VSRAM_REMAP_2_SHIFT 8
+#define VSRAM_REMAP_2_MASK 0x700
+#define VSRAM_REMAP_1_SHIFT 4
+#define VSRAM_REMAP_1_MASK 0x70
+#define VSRAM_REMAP_0_SHIFT 0
+#define VSRAM_REMAP_0_MASK 0x7
+
+/* DVFSRC_HALT_SW_CONTROL(0x10012000 + 0x94) */
+#define RGU_HALT_INV_SHIFT 1
+#define RGU_HALT_INV_MASK 0x2
+#define RGU_HALT_DISABLE_SHIFT 0
+#define RGU_HALT_DISABLE_MASK 0x1
+
+/* DVFSRC_INT(0x10012000 + 0x98) */
+#define MD_SCENARIO_INT_SHIFT 14
+#define MD_SCENARIO_INT_MASK 0x4000
+#define BW_MON_5_INT_SHIFT 13
+#define BW_MON_5_INT_MASK 0x2000
+#define BW_MON_4_INT_SHIFT 12
+#define BW_MON_4_INT_MASK 0x1000
+#define BW_MON_3_INT_SHIFT 11
+#define BW_MON_3_INT_MASK 0x800
+#define BW_MON_2_INT_SHIFT 10
+#define BW_MON_2_INT_MASK 0x400
+#define BW_MON_1_INT_SHIFT 9
+#define BW_MON_1_INT_MASK 0x200
+#define BW_MON_0_INT_SHIFT 8
+#define BW_MON_0_INT_MASK 0x100
+#define SW_4_INT_SHIFT 7
+#define SW_4_INT_MASK 0x80
+#define SW_3_INT_SHIFT 6
+#define SW_3_INT_MASK 0x40
+#define SW_2_INT_SHIFT 5
+#define SW_2_INT_MASK 0x20
+#define SW_1_INT_SHIFT 4
+#define SW_1_INT_MASK 0x10
+#define SW_0_INT_SHIFT 3
+#define SW_0_INT_MASK 0x8
+#define LEVEL_INT_SHIFT 2
+#define LEVEL_INT_MASK 0x4
+#define TIMEOUT_INT_SHIFT 1
+#define TIMEOUT_INT_MASK 0x2
+#define LATENCY_INT_SHIFT 0
+#define LATENCY_INT_MASK 0x1
+
+/* DVFSRC_INT_EN(0x10012000 + 0x9C) */
+#define MD_SCENARIO_INT_EN_SHIFT 14
+#define MD_SCENARIO_INT_EN_MASK 0x4000
+#define BW_MON_5_INT_EN_SHIFT 13
+#define BW_MON_5_INT_EN_MASK 0x2000
+#define BW_MON_4_INT_EN_SHIFT 12
+#define BW_MON_4_INT_EN_MASK 0x1000
+#define BW_MON_3_INT_EN_SHIFT 11
+#define BW_MON_3_INT_EN_MASK 0x800
+#define BW_MON_2_INT_EN_SHIFT 10
+#define BW_MON_2_INT_EN_MASK 0x400
+#define BW_MON_1_INT_EN_SHIFT 9
+#define BW_MON_1_INT_EN_MASK 0x200
+#define BW_MON_0_INT_EN_SHIFT 8
+#define BW_MON_0_INT_EN_MASK 0x100
+#define SW_4_INT_EN_SHIFT 7
+#define SW_4_INT_EN_MASK 0x80
+#define SW_3_INT_EN_SHIFT 6
+#define SW_3_INT_EN_MASK 0x40
+#define SW_2_INT_EN_SHIFT 5
+#define SW_2_INT_EN_MASK 0x20
+#define SW_1_INT_EN_SHIFT 4
+#define SW_1_INT_EN_MASK 0x10
+#define SW_0_INT_EN_SHIFT 3
+#define SW_0_INT_EN_MASK 0x8
+#define LEVEL_INT_EN_SHIFT 2
+#define LEVEL_INT_EN_MASK 0x4
+#define TIMEOUT_INT_EN_SHIFT 1
+#define TIMEOUT_INT_EN_MASK 0x2
+#define LATENCY_INT_EN_SHIFT 0
+#define LATENCY_INT_EN_MASK 0x1
+
+/* DVFSRC_INT_CLR(0x10012000 + 0xA0) */
+#define MD_SCENARIO_INT_CLR_SHIFT 14
+#define MD_SCENARIO_INT_CLR_MASK 0x4000
+#define BW_MON_5_INT_CLR_SHIFT 13
+#define BW_MON_5_INT_CLR_MASK 0x2000
+#define BW_MON_4_INT_CLR_SHIFT 12
+#define BW_MON_4_INT_CLR_MASK 0x1000
+#define BW_MON_3_INT_CLR_SHIFT 11
+#define BW_MON_3_INT_CLR_MASK 0x800
+#define BW_MON_2_INT_CLR_SHIFT 10
+#define BW_MON_2_INT_CLR_MASK 0x400
+#define BW_MON_1_INT_CLR_SHIFT 9
+#define BW_MON_1_INT_CLR_MASK 0x200
+#define BW_MON_0_INT_CLR_SHIFT 8
+#define BW_MON_0_INT_CLR_MASK 0x100
+#define SW_4_INT_CLR_SHIFT 7
+#define SW_4_INT_CLR_MASK 0x80
+#define SW_3_INT_CLR_SHIFT 6
+#define SW_3_INT_CLR_MASK 0x40
+#define SW_2_INT_CLR_SHIFT 5
+#define SW_2_INT_CLR_MASK 0x20
+#define SW_1_INT_CLR_SHIFT 4
+#define SW_1_INT_CLR_MASK 0x10
+#define SW_0_INT_CLR_SHIFT 3
+#define SW_0_INT_CLR_MASK 0x8
+#define LEVEL_INT_CLR_SHIFT 2
+#define LEVEL_INT_CLR_MASK 0x4
+#define TIMEOUT_INT_CLR_SHIFT 1
+#define TIMEOUT_INT_CLR_MASK 0x2
+#define LATENCY_INT_CLR_SHIFT 0
+#define LATENCY_INT_CLR_MASK 0x1
+
+/* DVFSRC_BW_MON_WINDOW(0x10012000 + 0xA4) */
+#define BW_MON_5_WINDOW_SHIFT 20
+#define BW_MON_5_WINDOW_MASK 0xf00000
+#define BW_MON_4_WINDOW_SHIFT 16
+#define BW_MON_4_WINDOW_MASK 0xf0000
+#define BW_MON_3_WINDOW_SHIFT 12
+#define BW_MON_3_WINDOW_MASK 0xf000
+#define BW_MON_2_WINDOW_SHIFT 8
+#define BW_MON_2_WINDOW_MASK 0xf00
+#define BW_MON_1_WINDOW_SHIFT 4
+#define BW_MON_1_WINDOW_MASK 0xf0
+#define BW_MON_0_WINDOW_SHIFT 0
+#define BW_MON_0_WINDOW_MASK 0xf
+
+/* DVFSRC_BW_MON_THRES_1(0x10012000 + 0xA8) */
+#define BW_MON_2_BIT1_THRES_SHIFT 20
+#define BW_MON_2_BIT1_THRES_MASK 0xf00000
+#define BW_MON_2_BIT0_THRES_SHIFT 16
+#define BW_MON_2_BIT0_THRES_MASK 0xf0000
+#define BW_MON_1_BIT1_THRES_SHIFT 12
+#define BW_MON_1_BIT1_THRES_MASK 0xf000
+#define BW_MON_1_BIT0_THRES_SHIFT 8
+#define BW_MON_1_BIT0_THRES_MASK 0xf00
+#define BW_MON_0_BIT1_THRES_SHIFT 4
+#define BW_MON_0_BIT1_THRES_MASK 0xf0
+#define BW_MON_0_BIT0_THRES_SHIFT 0
+#define BW_MON_0_BIT0_THRES_MASK 0xf
+
+/* DVFSRC_BW_MON_THRES_2(0x10012000 + 0xAC) */
+#define BW_MON_5_BIT1_THRES_SHIFT 20
+#define BW_MON_5_BIT1_THRES_MASK 0xf00000
+#define BW_MON_5_BIT0_THRES_SHIFT 16
+#define BW_MON_5_BIT0_THRES_MASK 0xf0000
+#define BW_MON_4_BIT1_THRES_SHIFT 12
+#define BW_MON_4_BIT1_THRES_MASK 0xf000
+#define BW_MON_4_BIT0_THRES_SHIFT 8
+#define BW_MON_4_BIT0_THRES_MASK 0xf00
+#define BW_MON_3_BIT1_THRES_SHIFT 4
+#define BW_MON_3_BIT1_THRES_MASK 0xf0
+#define BW_MON_3_BIT0_THRES_SHIFT 0
+#define BW_MON_3_BIT0_THRES_MASK 0xf
+
+/* DVFSRC_MD_TURBO(0x10012000 + 0xB0) */
+#define MD_TURBO_THRES_SHIFT 16
+#define MD_TURBO_THRES_MASK 0x1fff0000
+#define MD_TURBO_SW_EN_SHIFT 1
+#define MD_TURBO_SW_EN_MASK 0x2
+#define MD_TURBO_SW_MODE_SHIFT 0
+#define MD_TURBO_SW_MODE_MASK 0x1
+
+/* DVFSRC_DEBOUNCE_FOUR(0x10012000 + 0xD0) */
+#define RG_DEBOUNCE_FOUR_SHIFT 0
+#define RG_DEBOUNCE_FOUR_MASK 0xffff
+
+/* DVFSRC_DEBOUNCE_RISE_FALL(0x10012000 + 0xD4) */
+#define RG_DEBOUNCE_FALL_SHIFT 16
+#define RG_DEBOUNCE_FALL_MASK 0xffff0000
+#define RG_DEBOUNCE_RISE_SHIFT 0
+#define RG_DEBOUNCE_RISE_MASK 0xffff
+
+/* DVFSRC_TIMEOUT_NEXTREQ(0x10012000 + 0xD8) */
+#define RG_NEXT_REQ_SHIFT 8
+#define RG_NEXT_REQ_MASK 0xffff00
+#define RG_REQ_TIMEOUT_SHIFT 0
+#define RG_REQ_TIMEOUT_MASK 0xff
+
+/* DVFSRC_LEVEL(0x10012000 + 0xDC) */
+#define CURRENT_LEVEL_SHIFT 16
+#define CURRENT_LEVEL_MASK 0xffff0000
+#define TARGET_LEVEL_SHIFT 0
+#define TARGET_LEVEL_MASK 0xffff
+
+/* DVFSRC_LEVEL_LABEL_0_1(0x10012000 + 0xE0) */
+#define LEVEL1_VMODEM_SHIFT 24
+#define LEVEL1_VMODEM_MASK 0x7000000
+#define LEVEL1_EMI_SHIFT 20
+#define LEVEL1_EMI_MASK 0x700000
+#define LEVEL1_VCORE_SHIFT 16
+#define LEVEL1_VCORE_MASK 0x70000
+#define LEVEL0_VMODEM_SHIFT 8
+#define LEVEL0_VMODEM_MASK 0x700
+#define LEVEL0_EMI_SHIFT 4
+#define LEVEL0_EMI_MASK 0x70
+#define LEVEL0_VCORE_SHIFT 0
+#define LEVEL0_VCORE_MASK 0x7
+
+/* DVFSRC_LEVEL_LABEL_2_3(0x10012000 + 0xE4) */
+#define LEVEL3_VMODEM_SHIFT 24
+#define LEVEL3_VMODEM_MASK 0x7000000
+#define LEVEL3_EMI_SHIFT 20
+#define LEVEL3_EMI_MASK 0x700000
+#define LEVEL3_VCORE_SHIFT 16
+#define LEVEL3_VCORE_MASK 0x70000
+#define LEVEL2_VMODEM_SHIFT 8
+#define LEVEL2_VMODEM_MASK 0x700
+#define LEVEL2_EMI_SHIFT 4
+#define LEVEL2_EMI_MASK 0x70
+#define LEVEL2_VCORE_SHIFT 0
+#define LEVEL2_VCORE_MASK 0x7
+
+/* DVFSRC_LEVEL_LABEL_4_5(0x10012000 + 0xE8) */
+#define LEVEL5_VMODEM_SHIFT 24
+#define LEVEL5_VMODEM_MASK 0x7000000
+#define LEVEL5_EMI_SHIFT 20
+#define LEVEL5_EMI_MASK 0x700000
+#define LEVEL5_VCORE_SHIFT 16
+#define LEVEL5_VCORE_MASK 0x70000
+#define LEVEL4_VMODEM_SHIFT 8
+#define LEVEL4_VMODEM_MASK 0x700
+#define LEVEL4_EMI_SHIFT 4
+#define LEVEL4_EMI_MASK 0x70
+#define LEVEL4_VCORE_SHIFT 0
+#define LEVEL4_VCORE_MASK 0x7
+
+/* DVFSRC_LEVEL_LABEL_6_7(0x10012000 + 0xEC) */
+#define LEVEL7_VMODEM_SHIFT 24
+#define LEVEL7_VMODEM_MASK 0x7000000
+#define LEVEL7_EMI_SHIFT 20
+#define LEVEL7_EMI_MASK 0x700000
+#define LEVEL7_VCORE_SHIFT 16
+#define LEVEL7_VCORE_MASK 0x70000
+#define LEVEL6_VMODEM_SHIFT 8
+#define LEVEL6_VMODEM_MASK 0x700
+#define LEVEL6_EMI_SHIFT 4
+#define LEVEL6_EMI_MASK 0x70
+#define LEVEL6_VCORE_SHIFT 0
+#define LEVEL6_VCORE_MASK 0x7
+
+/* DVFSRC_LEVEL_LABEL_8_9(0x10012000 + 0xF0) */
+#define LEVEL9_VMODEM_SHIFT 24
+#define LEVEL9_VMODEM_MASK 0x7000000
+#define LEVEL9_EMI_SHIFT 20
+#define LEVEL9_EMI_MASK 0x700000
+#define LEVEL9_VCORE_SHIFT 16
+#define LEVEL9_VCORE_MASK 0x70000
+#define LEVEL8_VMODEM_SHIFT 8
+#define LEVEL8_VMODEM_MASK 0x700
+#define LEVEL8_EMI_SHIFT 4
+#define LEVEL8_EMI_MASK 0x70
+#define LEVEL8_VCORE_SHIFT 0
+#define LEVEL8_VCORE_MASK 0x7
+
+/* DVFSRC_LEVEL_LABEL_10_11(0x10012000 + 0xF4) */
+#define LEVEL11_VMODEM_SHIFT 24
+#define LEVEL11_VMODEM_MASK 0x7000000
+#define LEVEL11_EMI_SHIFT 20
+#define LEVEL11_EMI_MASK 0x700000
+#define LEVEL11_VCORE_SHIFT 16
+#define LEVEL11_VCORE_MASK 0x70000
+#define LEVEL10_VMODEM_SHIFT 8
+#define LEVEL10_VMODEM_MASK 0x700
+#define LEVEL10_EMI_SHIFT 4
+#define LEVEL10_EMI_MASK 0x70
+#define LEVEL10_VCORE_SHIFT 0
+#define LEVEL10_VCORE_MASK 0x7
+
+/* DVFSRC_LEVEL_LABEL_12_13(0x10012000 + 0xF8) */
+#define LEVEL13_VMODEM_SHIFT 24
+#define LEVEL13_VMODEM_MASK 0x7000000
+#define LEVEL13_EMI_SHIFT 20
+#define LEVEL13_EMI_MASK 0x700000
+#define LEVEL13_VCORE_SHIFT 16
+#define LEVEL13_VCORE_MASK 0x70000
+#define LEVEL12_VMODEM_SHIFT 8
+#define LEVEL12_VMODEM_MASK 0x700
+#define LEVEL12_EMI_SHIFT 4
+#define LEVEL12_EMI_MASK 0x70
+#define LEVEL12_VCORE_SHIFT 0
+#define LEVEL12_VCORE_MASK 0x7
+
+/* DVFSRC_LEVEL_LABEL_14_15(0x10012000 + 0xFC) */
+#define LEVEL15_VMODEM_SHIFT 24
+#define LEVEL15_VMODEM_MASK 0x7000000
+#define LEVEL15_EMI_SHIFT 20
+#define LEVEL15_EMI_MASK 0x700000
+#define LEVEL15_VCORE_SHIFT 16
+#define LEVEL15_VCORE_MASK 0x70000
+#define LEVEL14_VMODEM_SHIFT 8
+#define LEVEL14_VMODEM_MASK 0x700
+#define LEVEL14_EMI_SHIFT 4
+#define LEVEL14_EMI_MASK 0x70
+#define LEVEL14_VCORE_SHIFT 0
+#define LEVEL14_VCORE_MASK 0x7
+
+/* DVFSRC_MM_BW_0(0x10012000 + 0x100) */
+#define MM_BW_0_SHIFT 0
+#define MM_BW_0_MASK 0xffffffff
+
+/* DVFSRC_MM_BW_1(0x10012000 + 0x104) */
+#define MM_BW_1_SHIFT 0
+#define MM_BW_1_MASK 0xffffffff
+
+/* DVFSRC_MM_BW_2(0x10012000 + 0x108) */
+#define MM_BW_2_SHIFT 0
+#define MM_BW_2_MASK 0xffffffff
+
+/* DVFSRC_MM_BW_3(0x10012000 + 0x10C) */
+#define MM_BW_3_SHIFT 0
+#define MM_BW_3_MASK 0xffffffff
+
+/* DVFSRC_MM_BW_4(0x10012000 + 0x110) */
+#define MM_BW_4_SHIFT 0
+#define MM_BW_4_MASK 0xffffffff
+
+/* DVFSRC_MM_BW_5(0x10012000 + 0x114) */
+#define MM_BW_5_SHIFT 0
+#define MM_BW_5_MASK 0xffffffff
+
+/* DVFSRC_MM_BW_6(0x10012000 + 0x118) */
+#define MM_BW_6_SHIFT 0
+#define MM_BW_6_MASK 0xffffffff
+
+/* DVFSRC_MM_BW_7(0x10012000 + 0x11C) */
+#define MM_BW_7_SHIFT 0
+#define MM_BW_7_MASK 0xffffffff
+
+/* DVFSRC_MM_BW_8(0x10012000 + 0x120) */
+#define MM_BW_8_SHIFT 0
+#define MM_BW_8_MASK 0xffffffff
+
+/* DVFSRC_MM_BW_9(0x10012000 + 0x124) */
+#define MM_BW_9_SHIFT 0
+#define MM_BW_9_MASK 0xffffffff
+
+/* DVFSRC_MM_BW_10(0x10012000 + 0x128) */
+#define MM_BW_10_SHIFT 0
+#define MM_BW_10_MASK 0xffffffff
+
+/* DVFSRC_MM_BW_11(0x10012000 + 0x12C) */
+#define MM_BW_11_SHIFT 0
+#define MM_BW_11_MASK 0xffffffff
+
+/* DVFSRC_MM_BW_12(0x10012000 + 0x130) */
+#define MM_BW_12_SHIFT 0
+#define MM_BW_12_MASK 0xffffffff
+
+/* DVFSRC_MM_BW_13(0x10012000 + 0x134) */
+#define MM_BW_13_SHIFT 0
+#define MM_BW_13_MASK 0xffffffff
+
+/* DVFSRC_MM_BW_14(0x10012000 + 0x138) */
+#define MM_BW_14_SHIFT 0
+#define MM_BW_14_MASK 0xffffffff
+
+/* DVFSRC_MM_BW_15(0x10012000 + 0x13C) */
+#define MM_BW_15_SHIFT 0
+#define MM_BW_15_MASK 0xffffffff
+
+/* DVFSRC_MD_BW_0(0x10012000 + 0x140) */
+#define MD_BW_0_SHIFT 0
+#define MD_BW_0_MASK 0xffffffff
+
+/* DVFSRC_MD_BW_1(0x10012000 + 0x144) */
+#define MD_BW_1_SHIFT 0
+#define MD_BW_1_MASK 0xffffffff
+
+/* DVFSRC_MD_BW_2(0x10012000 + 0x148) */
+#define MD_BW_2_SHIFT 0
+#define MD_BW_2_MASK 0xffffffff
+
+/* DVFSRC_MD_BW_3(0x10012000 + 0x14C) */
+#define MD_BW_3_SHIFT 0
+#define MD_BW_3_MASK 0xffffffff
+
+/* DVFSRC_MD_BW_4(0x10012000 + 0x150) */
+#define MD_BW_4_SHIFT 0
+#define MD_BW_4_MASK 0xffffffff
+
+/* DVFSRC_MD_BW_5(0x10012000 + 0x154) */
+#define MD_BW_5_SHIFT 0
+#define MD_BW_5_MASK 0xffffffff
+
+/* DVFSRC_MD_BW_6(0x10012000 + 0x158) */
+#define MD_BW_6_SHIFT 0
+#define MD_BW_6_MASK 0xffffffff
+
+/* DVFSRC_MD_BW_7(0x10012000 + 0x15C) */
+#define MD_BW_7_SHIFT 0
+#define MD_BW_7_MASK 0xffffffff
+
+/* DVFSRC_SW_BW_0(0x10012000 + 0x160) */
+#define SW_BW_0_SHIFT 0
+#define SW_BW_0_MASK 0xff
+
+/* DVFSRC_SW_BW_1(0x10012000 + 0x164) */
+#define SW_BW_1_SHIFT 0
+#define SW_BW_1_MASK 0xff
+
+/* DVFSRC_SW_BW_2(0x10012000 + 0x168) */
+#define SW_BW_2_SHIFT 0
+#define SW_BW_2_MASK 0xff
+
+/* DVFSRC_SW_BW_3(0x10012000 + 0x16C) */
+#define SW_BW_3_SHIFT 0
+#define SW_BW_3_MASK 0xff
+
+/* DVFSRC_SW_BW_4(0x10012000 + 0x170) */
+#define SW_BW_4_SHIFT 0
+#define SW_BW_4_MASK 0xff
+
+/* DVFSRC_QOS_EN(0x10012000 + 0x180) */
+#define EN_FINAL_AVG_PEK_MAX_SHIFT 16
+#define EN_FINAL_AVG_PEK_MAX_MASK 0x10000
+#define EN_FINAL_PEK_SHIFT 15
+#define EN_FINAL_PEK_MASK 0x8000
+#define EN_FINAL_AVG_SHIFT 14
+#define EN_FINAL_AVG_MASK 0x4000
+#define EN_PEK_SW4_SHIFT 13
+#define EN_PEK_SW4_MASK 0x2000
+#define EN_PEK_SW3_SHIFT 12
+#define EN_PEK_SW3_MASK 0x1000
+#define EN_PEK_SW2_SHIFT 11
+#define EN_PEK_SW2_MASK 0x800
+#define EN_PEK_SW1_SHIFT 10
+#define EN_PEK_SW1_MASK 0x400
+#define EN_PEK_SW0_SHIFT 9
+#define EN_PEK_SW0_MASK 0x200
+#define EN_PEK_MD_SHIFT 8
+#define EN_PEK_MD_MASK 0x100
+#define EN_PEK_MM_SHIFT 7
+#define EN_PEK_MM_MASK 0x80
+#define EN_AVG_SW4_SHIFT 6
+#define EN_AVG_SW4_MASK 0x40
+#define EN_AVG_SW3_SHIFT 5
+#define EN_AVG_SW3_MASK 0x20
+#define EN_AVG_SW2_SHIFT 4
+#define EN_AVG_SW2_MASK 0x10
+#define EN_AVG_SW1_SHIFT 3
+#define EN_AVG_SW1_MASK 0x8
+#define EN_AVG_SW0_SHIFT 2
+#define EN_AVG_SW0_MASK 0x4
+#define EN_AVG_MD_SHIFT 1
+#define EN_AVG_MD_MASK 0x2
+#define EN_AVG_MM_SHIFT 0
+#define EN_AVG_MM_MASK 0x1
+
+/* DVFSRC_ISP_HRT(0x10012000 + 0x190) */
+#define ISP_HRT_SHIFT 0
+#define ISP_HRT_MASK 0xff
+
+/* DVFSRC_FORCE(0x10012000 + 0x300) */
+#define CURRENT_FORCE_SHIFT 16
+#define CURRENT_FORCE_MASK 0xffff0000
+#define TARGET_FORCE_SHIFT 0
+#define TARGET_FORCE_MASK 0xffff
+
+/* DVFSRC_SEC_SW_REQ(0x10012000 + 0x304) */
+#define EMI_SEC_SW_SHIFT 2
+#define EMI_SEC_SW_MASK 0xc
+#define VCORE_SEC_SW_SHIFT 0
+#define VCORE_SEC_SW_MASK 0x3
+
+/* DVFSRC_LAST(0x10012000 + 0x308) */
+#define LAST_ONE_SHIFT 0
+#define LAST_ONE_MASK 0x7
+
+/* DVFSRC_LAST_L(0x10012000 + 0x30C) */
+#define LAST_ONE_L_SHIFT 0
+#define LAST_ONE_L_MASK 0x7
+
+/* DVFSRC_MD_SCENARIO(0x10012000 + 0x310) */
+#define MD_SCENARIO_SHIFT 0
+#define MD_SCENARIO_MASK 0xffffffff
+
+/* DVFSRC_RECORD_0_0(0x10012000 + 0x400) */
+#define RECORD_0_SHIFT 0
+#define RECORD_0_MASK 0xffffffff
+
+/* DVFSRC_RECORD_0_1(0x10012000 + 0x404) */
+#define RECORD_0_SHIFT 0
+#define RECORD_0_MASK 0xffffffff
+
+/* DVFSRC_RECORD_0_2(0x10012000 + 0x408) */
+#define RECORD_0_SHIFT 0
+#define RECORD_0_MASK 0xffffffff
+
+/* DVFSRC_RECORD_1_0(0x10012000 + 0x40C) */
+#define RECORD_1_SHIFT 0
+#define RECORD_1_MASK 0xffffffff
+
+/* DVFSRC_RECORD_1_1(0x10012000 + 0x410) */
+#define RECORD_1_SHIFT 0
+#define RECORD_1_MASK 0xffffffff
+
+/* DVFSRC_RECORD_1_2(0x10012000 + 0x414) */
+#define RECORD_1_SHIFT 0
+#define RECORD_1_MASK 0xffffffff
+
+/* DVFSRC_RECORD_2_0(0x10012000 + 0x418) */
+#define RECORD_2_SHIFT 0
+#define RECORD_2_MASK 0xffffffff
+
+/* DVFSRC_RECORD_2_1(0x10012000 + 0x41C) */
+#define RECORD_2_SHIFT 0
+#define RECORD_2_MASK 0xffffffff
+
+/* DVFSRC_RECORD_2_2(0x10012000 + 0x420) */
+#define RECORD_2_SHIFT 0
+#define RECORD_2_MASK 0xffffffff
+
+/* DVFSRC_RECORD_3_0(0x10012000 + 0x424) */
+#define RECORD_3_SHIFT 0
+#define RECORD_3_MASK 0xffffffff
+
+/* DVFSRC_RECORD_3_1(0x10012000 + 0x428) */
+#define RECORD_3_SHIFT 0
+#define RECORD_3_MASK 0xffffffff
+
+/* DVFSRC_RECORD_3_2(0x10012000 + 0x42C) */
+#define RECORD_3_SHIFT 0
+#define RECORD_3_MASK 0xffffffff
+
+/* DVFSRC_RECORD_4_0(0x10012000 + 0x430) */
+#define RECORD_4_SHIFT 0
+#define RECORD_4_MASK 0xffffffff
+
+/* DVFSRC_RECORD_4_1(0x10012000 + 0x434) */
+#define RECORD_4_SHIFT 0
+#define RECORD_4_MASK 0xffffffff
+
+/* DVFSRC_RECORD_4_2(0x10012000 + 0x438) */
+#define RECORD_4_SHIFT 0
+#define RECORD_4_MASK 0xffffffff
+
+/* DVFSRC_RECORD_5_0(0x10012000 + 0x43C) */
+#define RECORD_5_SHIFT 0
+#define RECORD_5_MASK 0xffffffff
+
+/* DVFSRC_RECORD_5_1(0x10012000 + 0x440) */
+#define RECORD_5_SHIFT 0
+#define RECORD_5_MASK 0xffffffff
+
+/* DVFSRC_RECORD_5_2(0x10012000 + 0x444) */
+#define RECORD_5_SHIFT 0
+#define RECORD_5_MASK 0xffffffff
+
+/* DVFSRC_RECORD_6_0(0x10012000 + 0x448) */
+#define RECORD_6_SHIFT 0
+#define RECORD_6_MASK 0xffffffff
+
+/* DVFSRC_RECORD_6_1(0x10012000 + 0x44C) */
+#define RECORD_6_SHIFT 0
+#define RECORD_6_MASK 0xffffffff
+
+/* DVFSRC_RECORD_6_2(0x10012000 + 0x450) */
+#define RECORD_6_SHIFT 0
+#define RECORD_6_MASK 0xffffffff
+
+/* DVFSRC_RECORD_7_0(0x10012000 + 0x454) */
+#define RECORD_7_SHIFT 0
+#define RECORD_7_MASK 0xffffffff
+
+/* DVFSRC_RECORD_7_1(0x10012000 + 0x458) */
+#define RECORD_7_SHIFT 0
+#define RECORD_7_MASK 0xffffffff
+
+/* DVFSRC_RECORD_7_2(0x10012000 + 0x45C) */
+#define RECORD_7_SHIFT 0
+#define RECORD_7_MASK 0xffffffff
+
+/* DVFSRC_RECORD_0_L_0(0x10012000 + 0x460) */
+#define RECORD_0_L_SHIFT 0
+#define RECORD_0_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_0_L_1(0x10012000 + 0x464) */
+#define RECORD_0_L_SHIFT 0
+#define RECORD_0_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_0_L_2(0x10012000 + 0x468) */
+#define RECORD_0_L_SHIFT 0
+#define RECORD_0_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_1_L_0(0x10012000 + 0x46C) */
+#define RECORD_1_L_SHIFT 0
+#define RECORD_1_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_1_L_1(0x10012000 + 0x470) */
+#define RECORD_1_L_SHIFT 0
+#define RECORD_1_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_1_L_2(0x10012000 + 0x474) */
+#define RECORD_1_L_SHIFT 0
+#define RECORD_1_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_2_L_0(0x10012000 + 0x478) */
+#define RECORD_2_L_SHIFT 0
+#define RECORD_2_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_2_L_1(0x10012000 + 0x47C) */
+#define RECORD_2_L_SHIFT 0
+#define RECORD_2_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_2_L_2(0x10012000 + 0x480) */
+#define RECORD_2_L_SHIFT 0
+#define RECORD_2_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_3_L_0(0x10012000 + 0x484) */
+#define RECORD_3_L_SHIFT 0
+#define RECORD_3_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_3_L_1(0x10012000 + 0x488) */
+#define RECORD_3_L_SHIFT 0
+#define RECORD_3_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_3_L_2(0x10012000 + 0x48C) */
+#define RECORD_3_L_SHIFT 0
+#define RECORD_3_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_4_L_0(0x10012000 + 0x490) */
+#define RECORD_4_L_SHIFT 0
+#define RECORD_4_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_4_L_1(0x10012000 + 0x494) */
+#define RECORD_4_L_SHIFT 0
+#define RECORD_4_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_4_L_2(0x10012000 + 0x498) */
+#define RECORD_4_L_SHIFT 0
+#define RECORD_4_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_5_L_0(0x10012000 + 0x49C) */
+#define RECORD_5_L_SHIFT 0
+#define RECORD_5_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_5_L_1(0x10012000 + 0x4A0) */
+#define RECORD_5_L_SHIFT 0
+#define RECORD_5_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_5_L_2(0x10012000 + 0x4A4) */
+#define RECORD_5_L_SHIFT 0
+#define RECORD_5_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_6_L_0(0x10012000 + 0x4A8) */
+#define RECORD_6_L_SHIFT 0
+#define RECORD_6_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_6_L_1(0x10012000 + 0x4AC) */
+#define RECORD_6_L_SHIFT 0
+#define RECORD_6_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_6_L_2(0x10012000 + 0x4B0) */
+#define RECORD_6_L_SHIFT 0
+#define RECORD_6_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_7_L_0(0x10012000 + 0x4B4) */
+#define RECORD_7_L_SHIFT 0
+#define RECORD_7_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_7_L_1(0x10012000 + 0x4B8) */
+#define RECORD_7_L_SHIFT 0
+#define RECORD_7_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_7_L_2(0x10012000 + 0x4BC) */
+#define RECORD_7_L_SHIFT 0
+#define RECORD_7_L_MASK 0xffffffff
+
+/* DVFSRC_RECORD_MD_0(0x10012000 + 0x4C0) */
+#define RECORD_MD_0_SHIFT 0
+#define RECORD_MD_0_MASK 0xffffffff
+
+/* DVFSRC_RECORD_MD_1(0x10012000 + 0x4C4) */
+#define RECORD_MD_1_SHIFT 0
+#define RECORD_MD_1_MASK 0xffffffff
+
+/* DVFSRC_RECORD_MD_2(0x10012000 + 0x4C8) */
+#define RECORD_MD_2_SHIFT 0
+#define RECORD_MD_2_MASK 0xffffffff
+
+/* DVFSRC_RECORD_MD_3(0x10012000 + 0x4CC) */
+#define RECORD_MD_3_SHIFT 0
+#define RECORD_MD_3_MASK 0xffffffff
+
+/* DVFSRC_RECORD_MD_4(0x10012000 + 0x4D0) */
+#define RECORD_MD_4_SHIFT 0
+#define RECORD_MD_4_MASK 0xffffffff
+
+/* DVFSRC_RECORD_MD_5(0x10012000 + 0x4D4) */
+#define RECORD_MD_5_SHIFT 0
+#define RECORD_MD_5_MASK 0xffffffff
+
+/* DVFSRC_RECORD_MD_6(0x10012000 + 0x4D8) */
+#define RECORD_MD_6_SHIFT 0
+#define RECORD_MD_6_MASK 0xffffffff
+
+/* DVFSRC_RECORD_MD_7(0x10012000 + 0x4DC) */
+#define RECORD_MD_7_SHIFT 0
+#define RECORD_MD_7_MASK 0xffffffff
+
+/* DVFSRC_RECORD_COUNT(0x10012000 + 0x4F0) */
+#define COUNTER_SHIFT 0
+#define COUNTER_MASK 0x7fffff
+
+/* DVFSRC_RSRV_0(0x10012000 + 0x600) */
+#define RSRV_0_SHIFT 6
+#define RSRV_0_MASK 0xffffffc0
+#define RSRV_STATUS_SHIFT 0
+#define RSRV_STATUS_MASK 0x3f
+
+/* DVFSRC_RSRV_1(0x10012000 + 0x604) */
+#define RSRV_1_SHIFT 4
+#define RSRV_1_MASK 0xfffffff0
+#define ECO_FUL_SHIFT 3
+#define ECO_FUL_MASK 0x8
+#define DVFS_FUL_SHIFT 2
+#define DVFS_FUL_MASK 0x4
+#define MASK2_EN_SHIFT 1
+#define MASK2_EN_MASK 0x2
+#define MASK_EN_SHIFT 0
+#define MASK_EN_MASK 0x1
+
+/* DVFSRC_RSRV_2(0x10012000 + 0x608) */
+#define RSRV_2_SHIFT 0
+#define RSRV_2_MASK 0xffffffff
+
+/* DVFSRC_RSRV_3(0x10012000 + 0x60C) */
+#define RSRV_3_SHIFT 0
+#define RSRV_3_MASK 0xffffffff
+
+/* DVFSRC_RSRV_4(0x10012000 + 0x610) */
+#define RSRV_4_SHIFT 0
+#define RSRV_4_MASK 0xffffffff
+
+/* DVFSRC_RSRV_5(0x10012000 + 0x614) */
+#define RSRV_5_SHIFT 0
+#define RSRV_5_MASK 0xffffffff
+
+#endif /* __MTK_DVFSRC_REG_H */
diff --git a/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc_v2.c b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc_v2.c
new file mode 100644
index 0000000..f4859b7
--- /dev/null
+++ b/src/kernel/linux/v4.14/drivers/devfreq/mediatek/mt2731/mtk-dvfsrc_v2.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+#include <linux/devfreq.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/of.h>
+
+#include <governor.h>
+
+#ifdef CONFIG_MTK_AEE_FEATURE
+#include <mt-plat/aee.h>
+#endif
+#include <mtk_spm.h>
+#include "mtk-dvfsrc.h"
+#include "mtk-dvfsrc_reg.h"
+
+static struct dvfsrc *dvfsrc;
+
+static int dvfsrc_target_array[DVFSRC_NUM_CLASSES];
+
+#define DVFSRC_REG(offset) (dvfsrc->regs + offset)
+
+u32 dvfsrc_read(u32 offset)
+{
+ return readl(DVFSRC_REG(offset));
+}
+
+void dvfsrc_write(u32 offset, u32 val)
+{
+ writel(val, DVFSRC_REG(offset));
+}
+
+static void dvfsrc_restore(void)
+{
+ commit_data(DVFSRC_DDR_OPP,
+ DVFSRC_DDR_OPP_DEFAULT_VALUE);
+ commit_data(DVFSRC_VCORE_OPP,
+ DVFSRC_VCORE_OPP_DEFAULT_VALUE);
+ commit_data(DVFSRC_VCORE_DVFS_FORCE_OPP,
+ DVFSRC_VCORE_DVFS_FORCE_OPP_DEFAULT_VALUE);
+}
+
+static void dvfsrc_target_restore(void)
+{
+ dvfsrc_target_array[DVFSRC_DDR_OPP]
+ = DVFSRC_DDR_OPP_DEFAULT_VALUE;
+ dvfsrc_target_array[DVFSRC_VCORE_OPP]
+ = DVFSRC_VCORE_OPP_DEFAULT_VALUE;
+}
+
+void dvfsrc_enable(int dvfsrc_en)
+{
+ if (dvfsrc_en > 1 || dvfsrc_en < 0)
+ return;
+
+ dvfsrc->dvfsrc_enabled = dvfsrc_en;
+ dvfsrc->opp_forced = 0;
+ sprintf(dvfsrc->force_start, "0");
+ sprintf(dvfsrc->force_end, "0");
+
+ dvfsrc_restore();
+ dvfsrc_target_restore();
+ if (dvfsrc_en)
+ dvfsrc_en |= (dvfsrc->dvfsrc_flag << 1);
+}
+
+void dvfsrc_flag_set(int flag)
+{
+ dvfsrc->dvfsrc_flag = flag;
+}
+
+int dvfsrc_flag_get(void)
+{
+ return dvfsrc->dvfsrc_flag;
+}
+
+static int dvfsrc_common_init(void)
+{
+ dvfsrc_opp_level_mapping();
+ dvfsrc_opp_table_init();
+
+ return 0;
+}
+
+int is_dvfsrc_enabled(void)
+{
+ if (dvfsrc)
+ return dvfsrc->dvfsrc_enabled == 1;
+
+ return 0;
+}
+
+static void get_dvfsrc_info(char *p)
+{
+ p += sprintf(p, "%-24s: 0x%x\n",
+ "DVFSRC_VCORE_OPP",
+ dvfsrc_target_array[DVFSRC_VCORE_OPP]);
+ p += sprintf(p, "%-24s: 0x%x\n",
+ "DVFSRC_FORCE_OPP",
+ dvfsrc_target_array[DVFSRC_VCORE_DVFS_FORCE_OPP]);
+}
+char *dvfsrc_dump_reg(char *ptr)
+{
+ char buf[1024];
+
+ memset(buf, '\0', sizeof(buf));
+ get_opp_info(buf);
+ if (ptr)
+ ptr += sprintf(ptr, "%s\n", buf);
+ else
+ pr_info("%s\n", buf);
+
+ memset(buf, '\0', sizeof(buf));
+ get_dvfsrc_reg(buf);
+ if (ptr)
+ ptr += sprintf(ptr, "%s\n", buf);
+ else
+ pr_info("%s\n", buf);
+
+ memset(buf, '\0', sizeof(buf));
+ get_dvfsrc_record(buf);
+ if (ptr)
+ ptr += sprintf(ptr, "%s\n", buf);
+ else
+ pr_info("%s\n", buf);
+ memset(buf, '\0', sizeof(buf));
+ get_spm_reg(buf);
+ if (ptr)
+ ptr += sprintf(ptr, "%s\n", buf);
+ else
+ pr_info("%s\n", buf);
+ memset(buf, '\0', sizeof(buf));
+ get_dvfsrc_info(buf);
+ if (ptr)
+ ptr += sprintf(ptr, "%s\n", buf);
+ else
+ pr_info("%s\n", buf);
+ return ptr;
+}
+
+static void get_dvfsrc_latch_reg(char *p)
+{
+ u32 i;
+
+ for (i = 0x460; i <= 0x4BC; i += 4)
+ p += sprintf(p, "DVFSRC[0x%x]:0x%x\n",
+ i, dvfsrc_read(i));
+}
+
+char *dvfsrc_dump_lacth_reg(char *ptr)
+{
+ char buf[1024];
+
+ memset(buf, '\0', sizeof(buf));
+ get_dvfsrc_latch_reg(buf);
+ if (ptr)
+ ptr += sprintf(ptr, "%s\n", buf);
+ else
+ pr_info("%s\n", buf);
+ return ptr;
+}
+
+static struct devfreq_dev_profile devfreq_profile = {
+ .polling_ms = 0,
+};
+
+static int governor_event_handler(struct devfreq *devfreq,
+ unsigned int event, void *data)
+{
+ switch (event) {
+ case DEVFREQ_GOV_SUSPEND:
+ break;
+
+ case DEVFREQ_GOV_RESUME:
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+static struct devfreq_governor dvfsrc_governor = {
+ .name = "dvfsrc",
+ .event_handler = governor_event_handler,
+};
+
+/* DVFSRC Set Request */
+int dvfsrc_get_reguest(unsigned int id)
+{
+ int ret = -1;
+
+ if (id >= DVFSRC_NUM_CLASSES) {
+ pr_info("%s:The request is not supported %d\n", __func__, id);
+ return ret;
+ }
+
+ return dvfsrc_target_array[id];
+}
+EXPORT_SYMBOL(dvfsrc_get_reguest);
+
+void dvfsrc_set_ddr_opp(int level)
+{
+ commit_data(DVFSRC_DDR_OPP, level);
+ dvfsrc_target_array[DVFSRC_DDR_OPP] = level;
+}
+EXPORT_SYMBOL(dvfsrc_set_ddr_opp);
+
+void dvfsrc_set_vcore_opp(int level)
+{
+ commit_data(DVFSRC_VCORE_OPP, level);
+ dvfsrc_target_array[DVFSRC_VCORE_OPP] = level;
+}
+EXPORT_SYMBOL(dvfsrc_set_vcore_opp);
+
+void dvfsrc_set_vcore_dvfs_force_opp(int level)
+{
+ commit_data(DVFSRC_VCORE_DVFS_FORCE_OPP, level);
+ dvfsrc_target_array[DVFSRC_VCORE_DVFS_FORCE_OPP] = level;
+}
+EXPORT_SYMBOL(dvfsrc_set_vcore_dvfs_force_opp);
+
+void dvfsrc_set_vcore_dvfs_force_workaround_opp(void)
+{
+ commit_data(DVFSRC_VCORE_DVFS_FORCE_OPP_WORKAROUND, 0);
+}
+EXPORT_SYMBOL(dvfsrc_set_vcore_dvfs_force_workaround_opp);
+
+static int dvfsrc_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct resource *res;
+ struct device_node *np = pdev->dev.of_node;
+
+ dvfsrc = devm_kzalloc(&pdev->dev, sizeof(*dvfsrc), GFP_KERNEL);
+ if (!dvfsrc)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ dvfsrc->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(dvfsrc->regs))
+ return PTR_ERR(dvfsrc->regs);
+
+ platform_set_drvdata(pdev, dvfsrc);
+ dvfsrc->dev = &pdev->dev;
+
+ dvfsrc->devfreq = devm_devfreq_add_device(&pdev->dev,
+ &devfreq_profile,
+ "dvfsrc",
+ NULL);
+
+ ret = dvfsrc_add_interface(&pdev->dev);
+ if (ret)
+ return ret;
+
+ dvfsrc_common_init();
+
+ if (of_property_read_u32(np, "dvfsrc_flag",
+ (u32 *) &dvfsrc->dvfsrc_flag))
+ dvfsrc->dvfsrc_flag = 0;
+
+ dvfsrc_platform_init(dvfsrc);
+
+ pr_info("%s: init done\n", __func__);
+
+ return 0;
+}
+
+static int dvfsrc_remove(struct platform_device *pdev)
+{
+ dvfsrc_remove_interface(&pdev->dev);
+ return 0;
+}
+
+static const struct of_device_id dvfsrc_of_match[] = {
+ { .compatible = "mediatek,dvfsrc" },
+ { .compatible = "mediatek,dvfsrc-v2" },
+ { },
+};
+
+MODULE_DEVICE_TABLE(of, dvfsrc_of_match);
+
+static __maybe_unused int dvfsrc_suspend(struct device *dev)
+{
+ int ret = 0;
+
+ if (dvfsrc->suspend) {
+ ret = dvfsrc->suspend(dvfsrc);
+ if (ret)
+ return ret;
+ }
+
+ ret = devfreq_suspend_device(dvfsrc->devfreq);
+ if (ret < 0) {
+ dev_dbg(dev, "failed to suspend the devfreq devices\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static __maybe_unused int dvfsrc_resume(struct device *dev)
+{
+ int ret = 0;
+
+ if (dvfsrc->resume) {
+ ret = dvfsrc->resume(dvfsrc);
+ if (ret)
+ return ret;
+ }
+
+ ret = devfreq_resume_device(dvfsrc->devfreq);
+ if (ret < 0) {
+ dev_dbg(dev, "failed to resume the devfreq devices\n");
+ return ret;
+ }
+ return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(dvfsrc_pm, dvfsrc_suspend,
+ dvfsrc_resume);
+
+static struct platform_driver dvfsrc_driver = {
+ .probe = dvfsrc_probe,
+ .remove = dvfsrc_remove,
+ .driver = {
+ .name = "dvfsrc",
+ .pm = &dvfsrc_pm,
+ .of_match_table = dvfsrc_of_match,
+ },
+};
+
+static int __init dvfsrc_init(void)
+{
+ int ret = 0;
+
+ ret = devfreq_add_governor(&dvfsrc_governor);
+ if (ret) {
+ pr_info("%s: failed to add governor: %d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = platform_driver_register(&dvfsrc_driver);
+ if (ret)
+ devfreq_remove_governor(&dvfsrc_governor);
+
+ return ret;
+}
+late_initcall_sync(dvfsrc_init)
+
+static void __exit dvfsrc_exit(void)
+{
+ int ret = 0;
+
+ platform_driver_unregister(&dvfsrc_driver);
+
+ ret = devfreq_remove_governor(&dvfsrc_governor);
+ if (ret)
+ pr_info("%s: failed to remove governor: %d\n", __func__, ret);
+}
+module_exit(dvfsrc_exit)
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("dvfsrc driver");