aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShangbing Hu <shangbing.hu@mediatek.com>2016-07-13 06:40:20 +0800
committerShangbing Hu <shangbing.hu@mediatek.com>2016-07-14 11:25:39 +0800
commitf36ed554c3fea0bedf6b183944396fde22edeaf3 (patch)
treee8929e3e488f7eafbbea3b7d83922b27a74357ef
parentc858d97915320ffb5067801096d87edb0c9c2a60 (diff)
[ALPS02768792] HDMI: add openpackage 8193 support
[Detail] 1.modify .dts&.dtsi file according to amt6797_64 project 2.modify .dws file that reuse ext_disp i2c node from 0x39 to 0x1d 3.add open package related code to ext_disp which is switch by HDMI_OPEN_PACKAGE_SUPPORT macro 4.add MT8193 multibridge code 5.open HDMI & MT8193 in config file [Solution] HDMI_OPEN_PACKAGE_SUPPORT is default DISABLE when build for open package, we should enable this macro in src code MTK-Commit-Id: 7ce45ca43a300ee6f173bfd123d75bb7539f16de Change-Id: I4f37dba556356c0b48d155aba393b4ff0413e699 Signed-off-by: Shangbing Hu <shangbing.hu@mediatek.com> CR-Id: ALPS02768792 Feature: Driver
-rw-r--r--arch/arm64/boot/dts/amt6797_64_open.dts52
-rw-r--r--arch/arm64/boot/dts/mt6797.dtsi1
-rw-r--r--arch/arm64/configs/amt6797_64_open_debug_defconfig4
-rw-r--r--arch/arm64/configs/amt6797_64_open_defconfig4
-rw-r--r--drivers/misc/mediatek/ext_disp/extd_hdmi.c77
-rw-r--r--drivers/misc/mediatek/ext_disp/extd_hdmi.h1
-rw-r--r--drivers/misc/mediatek/hdmi/inc/hdmi_drv.h1
-rw-r--r--drivers/misc/mediatek/hdmi/mt8193/hdmi_drv.c68
-rw-r--r--drivers/misc/mediatek/hdmi/mt8193/mt8193table.h2
-rw-r--r--drivers/misc/mediatek/multibridge/mt6797/Makefile15
-rw-r--r--drivers/misc/mediatek/multibridge/mt6797/mt8193/Makefile24
-rw-r--r--drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193.h200
-rw-r--r--drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193_ckgen.h185
-rw-r--r--drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193_gpio.h211
-rw-r--r--drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193_iic.h24
-rw-r--r--drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193_pinmux.h371
-rw-r--r--drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_ckgen.c1097
-rw-r--r--drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_ckgen_vfy.c501
-rw-r--r--drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_gpio.c237
-rw-r--r--drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_iic.c479
-rw-r--r--drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_pinmux.c110
-rw-r--r--drivers/misc/mediatek/video/mt6797/dispsys/ddp_dpi.c67
22 files changed, 3719 insertions, 12 deletions
diff --git a/arch/arm64/boot/dts/amt6797_64_open.dts b/arch/arm64/boot/dts/amt6797_64_open.dts
index 246f4a6dab84..44dd09c24f3a 100644
--- a/arch/arm64/boot/dts/amt6797_64_open.dts
+++ b/arch/arm64/boot/dts/amt6797_64_open.dts
@@ -1488,3 +1488,55 @@
};
/* SCP DVFS GPIO end */
+
+/* USB XHCI GPIO start */
+&pio {
+ iddig_default: iddig_default {
+ };
+
+ gpio181_mode1_iddig: iddig_init {
+ pins_cmd_dat {
+ pins = <PINMUX_GPIO181__FUNC_IDDIG>;
+ slew-rate = <0>;
+ bias-pull-up = <00>;
+ };
+ };
+};
+
+&pio {
+ drvvbus_default: drvvbus_default {
+ };
+
+ gpio94_mode1_drvvbus_low: drvvbus_low {
+ pins_cmd_dat {
+ pins = <PINMUX_GPIO94__FUNC_USB_DRVVBUS>;
+ slew-rate = <1>;
+ output-low;
+ };
+ };
+
+ gpio94_mode1_drvvbus_high: drvvbus_high {
+ pins_cmd_dat {
+ pins = <PINMUX_GPIO94__FUNC_USB_DRVVBUS>;
+ slew-rate = <1>;
+ output-high;
+ };
+ };
+};
+
+&usb0 {
+ pinctrl-names = "iddig_default", "iddig_init";
+ pinctrl-0 = <&iddig_default>;
+ pinctrl-1 = <&gpio181_mode1_iddig>;
+ status = "okay";
+};
+
+&xhci0 {
+ pinctrl-names = "drvvbus_default", "drvvbus_low", "drvvbus_high";
+ pinctrl-0 = <&drvvbus_default>;
+ pinctrl-1 = <&gpio94_mode1_drvvbus_low>;
+ pinctrl-2 = <&gpio94_mode1_drvvbus_high>;
+ status = "okay";
+};
+
+/* USB XHCI GPIO start */
diff --git a/arch/arm64/boot/dts/mt6797.dtsi b/arch/arm64/boot/dts/mt6797.dtsi
index fdb6e9ed249e..d78b8ae1a172 100644
--- a/arch/arm64/boot/dts/mt6797.dtsi
+++ b/arch/arm64/boot/dts/mt6797.dtsi
@@ -774,6 +774,7 @@
vcn33_bt-supply = <&mt_pmic_vcn33_bt_ldo_reg>;
vcn33_wifi-supply = <&mt_pmic_vcn33_wifi_ldo_reg>;
mhl_12v-supply = <&mt_pmic_vgp3_ldo_reg>;
+ vldo28-supply = <&mt_pmic_vldo28_ldo_reg>;
};
/* End of regulators_supply */
};
diff --git a/arch/arm64/configs/amt6797_64_open_debug_defconfig b/arch/arm64/configs/amt6797_64_open_debug_defconfig
index 4881d8adf79d..b242b7fb63fa 100644
--- a/arch/arm64/configs/amt6797_64_open_debug_defconfig
+++ b/arch/arm64/configs/amt6797_64_open_debug_defconfig
@@ -176,6 +176,7 @@ CONFIG_ARCH_MTK_PROJECT="amt6797_64_open"
CONFIG_MT_ENG_BUILD=y
CONFIG_MTK_SHARED_SDCARD=y
CONFIG_MTK_GPT_SCHEME_SUPPORT=y
+CONFIG_MTK_DISABLE_PICACHU=y
CONFIG_MTK_FREQ_HOPPING=y
CONFIG_MTK_BQ25896_SUPPORT=y
CONFIG_CUSTOM_KERNEL_IMGSENSOR="ov23850_mipi_raw s5k3m2_mipi_raw s5k5e2ya_mipi_raw imx258_mipi_raw imx377_mipi_raw s5k2x8_mipi_raw"
@@ -237,6 +238,8 @@ CONFIG_MTK_SMI_EXT=y
# CONFIG_USB_MTK_HDRC is not set
CONFIG_MTK_MUSB_QMU_SUPPORT=y
CONFIG_MTK_VIBRATOR=y
+CONFIG_USB_XHCI_MTK=y
+CONFIG_USB_MTK_DUALMODE=y
CONFIG_MTK_MEMCFG=y
CONFIG_MTK_AEE_FEATURE=y
CONFIG_MTK_AEE_MRDUMP=y
@@ -385,6 +388,7 @@ CONFIG_HID_TOPSEED=y
CONFIG_HID_THRUSTMASTER=y
CONFIG_HID_ZEROPLUS=y
CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
CONFIG_USB_STORAGE=y
CONFIG_USB_STORAGE_DEBUG=y
CONFIG_USB_STORAGE_DATAFAB=y
diff --git a/arch/arm64/configs/amt6797_64_open_defconfig b/arch/arm64/configs/amt6797_64_open_defconfig
index eb0508d86f7b..19a712127f84 100644
--- a/arch/arm64/configs/amt6797_64_open_defconfig
+++ b/arch/arm64/configs/amt6797_64_open_defconfig
@@ -171,6 +171,7 @@ CONFIG_MTK_PLATFORM="mt6797"
CONFIG_ARCH_MTK_PROJECT="amt6797_64_open"
CONFIG_MTK_SHARED_SDCARD=y
CONFIG_MTK_GPT_SCHEME_SUPPORT=y
+CONFIG_MTK_DISABLE_PICACHU=y
CONFIG_MTK_FREQ_HOPPING=y
CONFIG_MTK_BQ25896_SUPPORT=y
CONFIG_CUSTOM_KERNEL_IMGSENSOR="ov23850_mipi_raw s5k3m2_mipi_raw s5k5e2ya_mipi_raw imx258_mipi_raw imx377_mipi_raw s5k2x8_mipi_raw"
@@ -232,6 +233,8 @@ CONFIG_MTK_SMI_EXT=y
# CONFIG_USB_MTK_HDRC is not set
CONFIG_MTK_MUSB_QMU_SUPPORT=y
CONFIG_MTK_VIBRATOR=y
+CONFIG_USB_XHCI_MTK=y
+CONFIG_USB_MTK_DUALMODE=y
CONFIG_MTK_AEE_FEATURE=y
CONFIG_MTK_CHIP=y
CONFIG_GATOR_DRIVER=y
@@ -376,6 +379,7 @@ CONFIG_HID_TOPSEED=y
CONFIG_HID_THRUSTMASTER=y
CONFIG_HID_ZEROPLUS=y
CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
CONFIG_USB_STORAGE=y
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
diff --git a/drivers/misc/mediatek/ext_disp/extd_hdmi.c b/drivers/misc/mediatek/ext_disp/extd_hdmi.c
index d8543399bb17..c90d1b4aaeb2 100644
--- a/drivers/misc/mediatek/ext_disp/extd_hdmi.c
+++ b/drivers/misc/mediatek/ext_disp/extd_hdmi.c
@@ -137,6 +137,15 @@ struct task_struct *hdmi_fence_release_task = NULL;
wait_queue_head_t hdmi_fence_release_wq;
atomic_t hdmi_fence_release_event = ATOMIC_INIT(0);
+/*#define HDMI_OPEN_PACAKAGE_SUPPORT*/
+
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+struct task_struct *hdmi_para_config_task = NULL;
+wait_queue_head_t hdmi_para_config_wq;
+atomic_t hdmi_para_config_event = ATOMIC_INIT(0);
+#endif
+
+
struct task_struct *hdmi_wait_vsync_task = NULL;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
@@ -397,7 +406,10 @@ int hdmi_get_support_info(void)
#endif
#ifdef MTK_AUDIO_MULTI_CHANNEL_SUPPORT
- temp = hdmi_drv->get_external_device_capablity();
+ if (hdmi_drv->get_external_device_capablity != NULL)
+ temp = hdmi_drv->get_external_device_capablity();
+ else
+ temp = 0x2 << 3;
#else
temp = 0x2 << 3;
#endif
@@ -516,6 +528,28 @@ static void _hdmi_rdma_irq_handler(DISP_MODULE_ENUM module, unsigned int param)
first_frame_done = 1;
}
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+static int hdmi_para_config_kthread(void *data)
+{
+
+ struct sched_param param = {.sched_priority = 94 }; /*RTPM_PRIO_SCRN_UPDATE*/
+
+ sched_setscheduler(current, SCHED_RR, &param);
+ for (;;) {
+
+ wait_event_interruptible(hdmi_para_config_wq, atomic_read(&hdmi_para_config_event));
+ atomic_set(&hdmi_para_config_event, 0);
+
+ hdmi_set_resolution(HDMI_VIDEO_1280x720p_60Hz);
+
+ if (kthread_should_stop())
+ break;
+ }
+
+ return 0;
+}
+#endif
+
static int hdmi_fence_release_kthread(void *data)
{
int layid = 0;
@@ -667,6 +701,14 @@ static enum HDMI_STATUS hdmi_drv_init(void)
wake_up_process(hdmi_fence_release_task);
}
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+ if (!hdmi_para_config_task) {
+ hdmi_para_config_task = kthread_create(hdmi_para_config_kthread,
+ NULL, "hdmi_fence_release_kthread");
+ wake_up_process(hdmi_para_config_task);
+ }
+#endif
+
if (!hdmi_3d_config_task) {
hdmi_3d_config_task = kthread_create(hdmi_3d_config_kthread, NULL, "hdmi_3d_config_kthread");
wake_up_process(hdmi_3d_config_task);
@@ -732,6 +774,7 @@ static void hdmi_state_reset(void)
rdmafpscnt = 0;
up(&hdmi_update_mutex);
+ hdmi_reschange = HDMI_VIDEO_RESOLUTION_NUM;
MMProfileLogEx(ddp_mmp_get_events()->Extd_State, MMProfileFlagEnd, Plugout, 0);
}
@@ -789,6 +832,14 @@ static void hdmi_state_reset(void)
hdmi_state_reset();
}
}
+
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+ if (hdmi_drv->get_state() == HDMI_STATE_ACTIVE) {
+ atomic_set(&hdmi_para_config_event, 1);
+ wake_up_interruptible(&hdmi_para_config_wq);
+ }
+#endif
+
}
/*static*/ void hdmi_power_off(void)
@@ -1002,6 +1053,11 @@ void hdmi_state_callback(enum HDMI_STATE state)
ged_dvfs_vsync_offset_event_switch(GED_DVFS_VSYNC_OFFSET_MHL_EVENT, true);
#endif
HDMI_LOG("[hdmi]%s, state = %d out!\n", __func__, state);
+
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+ atomic_set(&hdmi_para_config_event, 1);
+ wake_up_interruptible(&hdmi_para_config_wq);
+#endif
break;
}
default:
@@ -1035,6 +1091,9 @@ int hdmi_enable(int enable)
hdmi_drv->enter();
hdmi_drv_init();
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+ p->is_enabled = true;
+#endif
hdmi_power_on();
p->is_enabled = true;
} else {
@@ -1059,6 +1118,10 @@ int hdmi_power_enable(int enable)
{
HDMI_FUNC();
if (!p->is_enabled) {
+
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+ hdmi_enable(true);
+#endif
HDMI_LOG("return in %d\n", __LINE__);
return 0;
}
@@ -1487,12 +1550,15 @@ int hdmi_post_init(void)
return -1;
}
- hdmi_drv->set_util_funcs(&hdmi_utils);
+ if (hdmi_drv->set_util_funcs != NULL)
+ hdmi_drv->set_util_funcs(&hdmi_utils);
hdmi_params->init_config.vformat = HDMI_VIDEO_1280x720p_60Hz;
- hdmi_drv->get_params(hdmi_params);
+ if (hdmi_drv->get_params != NULL)
+ hdmi_drv->get_params(hdmi_params);
- hdmi_drv->init(); /* need to remove to power on function Donglei */
+ if (hdmi_drv->init != NULL)
+ hdmi_drv->init(); /* need to remove to power on function Donglei */
if (hdmi_drv->register_callback != NULL) {
boot_mode = (int)get_boot_mode();
if (boot_mode == FACTORY_BOOT || boot_mode == ATE_FACTORY_BOOT) {
@@ -1516,6 +1582,9 @@ int hdmi_post_init(void)
init_waitqueue_head(&hdmi_3d_config_wq);
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+ init_waitqueue_head(&hdmi_para_config_wq);
+#endif
Extd_DBG_Init();
return 0;
}
diff --git a/drivers/misc/mediatek/ext_disp/extd_hdmi.h b/drivers/misc/mediatek/ext_disp/extd_hdmi.h
index eea61b1ba495..2a9ab81676d8 100644
--- a/drivers/misc/mediatek/ext_disp/extd_hdmi.h
+++ b/drivers/misc/mediatek/ext_disp/extd_hdmi.h
@@ -218,6 +218,7 @@ void hdmi_power_off(void);
int hdmi_wait_vsync_debug(int enable);
int hdmi_dump_vendor_chip_register(void);
+int hdmi_set_resolution(int res);
extern void Extd_DBG_Init(void);
#endif
diff --git a/drivers/misc/mediatek/hdmi/inc/hdmi_drv.h b/drivers/misc/mediatek/hdmi/inc/hdmi_drv.h
index fc1bd1d31b59..e1689030038a 100644
--- a/drivers/misc/mediatek/hdmi/inc/hdmi_drv.h
+++ b/drivers/misc/mediatek/hdmi/inc/hdmi_drv.h
@@ -345,4 +345,5 @@ const struct HDMI_DRIVER *HDMI_GetDriver(void);
void Notify_AP_MHL_TX_Event(unsigned int event, unsigned int event_param, void *param);
extern int chip_device_id;
extern bool need_reset_usb_switch;
+extern struct device *ext_dev_context;
#endif /* __HDMI_DRV_H__ */
diff --git a/drivers/misc/mediatek/hdmi/mt8193/hdmi_drv.c b/drivers/misc/mediatek/hdmi/mt8193/hdmi_drv.c
index 29fde3469812..366972bfc5c9 100644
--- a/drivers/misc/mediatek/hdmi/mt8193/hdmi_drv.c
+++ b/drivers/misc/mediatek/hdmi/mt8193/hdmi_drv.c
@@ -19,7 +19,7 @@
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/miscdevice.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/workqueue.h>
@@ -28,7 +28,7 @@
#include <linux/earlysuspend.h>
#endif
#include <linux/platform_device.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
@@ -72,7 +72,11 @@
/*----------------------------------------------------------------------------*/
/* Debug message defination */
/*----------------------------------------------------------------------------*/
-
+/*#define HDMI_OPEN_PACAKAGE_SUPPORT*/
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+#include <linux/pinctrl/consumer.h>
+char *power_pin_name[2] = {"power_default", "power_up"};
+#endif
/*----------------------------------------------------------------------------*/
/* HDMI Timer */
/*----------------------------------------------------------------------------*/
@@ -294,7 +298,7 @@ static void mt8193_resume(void)
/*----------------------------------------------------------------------------*/
static int mt8193_video_config(enum HDMI_VIDEO_RESOLUTION vformat, enum HDMI_VIDEO_INPUT_FORMAT vin,
- enum HDMI_VIDEO_OUTPUT_FORMAT vout)
+ int vout)
{
HDMI_DEF_LOG("[hdmi]mt8193_video_config:%d\n", vformat);
@@ -378,9 +382,14 @@ void mt8193_set_mode(unsigned char ucMode)
int mt8193_power_on(void)
{
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+ int ret = 0;
+ struct pinctrl *power_pinctrl;
+ struct pinctrl_state *pin_state;
+#else
struct device_node *dn;
int bus_switch_pin;
-
+#endif
HDMI_DEF_LOG("[hdmi]mt8193_power_on_\n");
if (hdmi_powerenable == 1) {
@@ -402,10 +411,29 @@ int mt8193_power_on(void)
mt_set_gpio_out(GPIO_HDMI_POWER_CONTROL, GPIO_OUT_ONE);
HDMI_DEF_LOG("[hdmi]hdmi_5v_on\n");
#endif
-
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+ if (ext_dev_context == NULL) {
+ pr_err("Cannot find ext_dev_context!\n");
+ return 0;
+ }
+ power_pinctrl = devm_pinctrl_get(ext_dev_context);
+ if (IS_ERR(power_pinctrl)) {
+ ret = PTR_ERR(power_pinctrl);
+ pr_err("Cannot find mt8193 power pinctrl!\n");
+ return 0;
+ }
+ pin_state = pinctrl_lookup_state(power_pinctrl, power_pin_name[1]);
+ if (IS_ERR(pin_state)) {
+ ret = PTR_ERR(pin_state);
+ pr_err("Cannot find mt8193 power pin state!\n");
+ return 0;
+ }
+ pinctrl_select_state(power_pinctrl, pin_state);
+#else
dn = of_find_compatible_node(NULL, NULL, "mediatek,mt8193-hdmi");
bus_switch_pin = of_get_named_gpio(dn, "hdmi_power_gpios", 0);
gpio_direction_output(bus_switch_pin, 1);
+#endif
vWriteHdmiSYSMsk(HDMI_PWR_CTRL, hdmi_power_turnon, hdmi_power_turnon);
vWriteHdmiSYSMsk(HDMI_SYS_PWR_RST_B, hdmi_pwr_sys_sw_unreset, hdmi_pwr_sys_sw_unreset);
@@ -430,9 +458,14 @@ int mt8193_power_on(void)
void mt8193_power_off(void)
{
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+ int ret = 0;
+ struct pinctrl *power_pinctrl;
+ struct pinctrl_state *pin_state;
+#else
struct device_node *dn;
int bus_switch_pin;
-
+#endif
HDMI_DEF_LOG("[hdmi]mt8193_power_off\n");
if (hdmi_powerenable == 0) {
HDMI_DEF_LOG("[hdmi]already power off, return\n");
@@ -459,10 +492,29 @@ void mt8193_power_off(void)
mt_set_gpio_out(GPIO_HDMI_POWER_CONTROL, GPIO_OUT_ZERO);
HDMI_DEF_LOG("[hdmi]hdmi_5v_off\n");
#endif
-
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+ if (ext_dev_context == NULL) {
+ pr_err("Cannot find ext_dev_context!\n");
+ return;
+ }
+ power_pinctrl = devm_pinctrl_get(ext_dev_context);
+ if (IS_ERR(power_pinctrl)) {
+ ret = PTR_ERR(power_pinctrl);
+ pr_err("Cannot find mt8193 power pinctrl! ret = %d\n", ret);
+ return;
+ }
+ pin_state = pinctrl_lookup_state(power_pinctrl, power_pin_name[0]);
+ if (IS_ERR(pin_state)) {
+ ret = PTR_ERR(pin_state);
+ pr_err("Cannot find mt8193 power pin state! ret = %d\n", ret);
+ return;
+ }
+ pinctrl_select_state(power_pinctrl, pin_state);
+#else
dn = of_find_compatible_node(NULL, NULL, "mediatek,mt8193-hdmi");
bus_switch_pin = of_get_named_gpio(dn, "hdmi_power_gpios", 0);
gpio_direction_output(bus_switch_pin, 0);
+#endif
vWriteHdmiSYSMsk(HDMI_PWR_CTRL, hdmi_clock_off, hdmi_clock_off);
vWriteHdmiSYSMsk(HDMI_PWR_CTRL, hdmi_iso_en, hdmi_iso_en);
diff --git a/drivers/misc/mediatek/hdmi/mt8193/mt8193table.h b/drivers/misc/mediatek/hdmi/mt8193/mt8193table.h
index cd631462ca75..925ef6dd96e0 100644
--- a/drivers/misc/mediatek/hdmi/mt8193/mt8193table.h
+++ b/drivers/misc/mediatek/hdmi/mt8193/mt8193table.h
@@ -30,6 +30,8 @@ enum HDMI_VIDEO_RESOLUTION {
HDMI_VIDEO_1920x1080p_29Hz, /* a */
HDMI_VIDEO_1920x1080p_60Hz, /* b */
HDMI_VIDEO_1920x1080p_50Hz, /* c */
+ HDMI_VIDEO_2160p_DSC_30Hz = 0x13,
+ HDMI_VIDEO_2160p_DSC_24Hz = 0x14,
HDMI_VIDEO_RESOLUTION_NUM
};
diff --git a/drivers/misc/mediatek/multibridge/mt6797/Makefile b/drivers/misc/mediatek/multibridge/mt6797/Makefile
new file mode 100644
index 000000000000..44f1c19c2723
--- /dev/null
+++ b/drivers/misc/mediatek/multibridge/mt6797/Makefile
@@ -0,0 +1,15 @@
+#
+# Copyright (C) 2015 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_MTK_MULTIBRIDGE_SUPPORT) += mt8193/
diff --git a/drivers/misc/mediatek/multibridge/mt6797/mt8193/Makefile b/drivers/misc/mediatek/multibridge/mt6797/mt8193/Makefile
new file mode 100644
index 000000000000..767279b19ced
--- /dev/null
+++ b/drivers/misc/mediatek/multibridge/mt6797/mt8193/Makefile
@@ -0,0 +1,24 @@
+#
+# Copyright (C) 2015 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.
+#
+
+
+ifeq ($(CONFIG_MTK_MULTIBRIDGE_SUPPORT),y)
+
+ccflags-y += -I$(srctree)/drivers/misc/mediatek/multibridge/$(CONFIG_MTK_PLATFORM)/mt8193/inc
+
+obj-y += mt8193_ckgen.o
+obj-y += mt8193_ckgen_vfy.o
+obj-y += mt8193_gpio.o
+obj-y += mt8193_iic.o
+obj-y += mt8193_pinmux.o
+endif \ No newline at end of file
diff --git a/drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193.h b/drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193.h
new file mode 100644
index 000000000000..d70d6cababd9
--- /dev/null
+++ b/drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef MT8193_H
+#define MT8193_H
+
+
+#include <generated/autoconf.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/kthread.h>
+#include <linux/vmalloc.h>
+#include <linux/uaccess.h>
+#include <linux/atomic.h>
+#include <asm/cacheflush.h>
+#include <linux/io.h>
+
+#include <mach/irqs.h>
+
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/cdev.h>
+#include <asm/tlbflush.h>
+#include <asm/page.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+
+#include "mt8193_iic.h"
+
+#define CKGEN_BASE 0x1000
+
+
+#define REG_RW_BUS_CKCFG 0x000
+#define CLK_BUS_SEL_XTAL 0
+#define CLK_BUS_SEL_NFIPLL_D2 1
+#define CLK_BUS_SEL_NFIPLL_D3 2
+#define CLK_BUS_SEL_XTAL_D2 3
+#define CLK_BUS_SEL_32K 4
+#define CLK_BUS_SEL_PAD_DPI0 5
+#define CLK_BUS_SEL_PAD_DPI1 6
+#define CLK_BUS_SEL_ROSC 7
+
+
+#define REG_RW_NFI_CKCFG 0x008
+#define CLK_NFI_SEL_NFIPLL 0
+#define CLK_NFI_SEL_NFIPLL_D2 1
+#define CLK_NFI_SEL_NFIPLL_D3 2
+#define CLK_NFI_SEL_XTAL_D1 3
+#define CLK_PDN_NFI (1U<<7)
+
+
+#define REG_RW_HDMI_PLL_CKCFG 0x00c
+#define CLK_HDMI_PLL_SEL_HDMIPLL 0
+#define CLK_HDMI_PLL_SEL_32K 1
+#define CLK_HDMI_PLL_SEL_XTAL_D1 2
+#define CLK_HDMI_PLL_SEL_NFIPLL 3
+#define CLK_PDN_HDMI_PLL (1U<<7)
+
+
+
+#define REG_RW_HDMI_DISP_CKCFG 0x010
+#define CLK_HDMI_DISP_SEL_DISP 0
+#define CLK_HDMI_DISP_SEL_32K 1
+#define CLK_HDMI_DISP_SEL_XTAL_D1 2
+#define CLK_HDMI_DISP_SEL_NFIPLL 3
+#define CLK_PDN_HDMI_DISP (1U<<7)
+
+
+#define REG_RW_LVDS_DISP_CKCFG 0x014
+#define CLK_LVDS_DISP_SEL_AD_VPLL_DPIX 0
+#define CLK_LVDS_DISP_SEL_32K 1
+#define CLK_LVDS_DISP_SEL_XTAL_D1 2
+#define CLK_LVDS_DISP_SEL_NFIPLL 3
+#define CLK_PDN_LVDS_DISP (1U<<7)
+
+
+#define REG_RW_LVDS_CTS_CKCFG 0x018
+#define CLK_LVDS_CTS_SEL_AD_VPLL_DPIX 0
+#define CLK_LVDS_CTS_SEL_32K 1
+#define CLK_LVDS_CTS_SEL_XTAL_D1 2
+#define CLK_LVDS_CTS_SEL_NFIPLL 3
+#define CLK_PDN_LVDS_CTS (1U<<7)
+
+
+#define REG_RW_PMUX0 0x200
+#define REG_RW_PMUX1 0x204
+#define REG_RW_PMUX2 0x208
+#define REG_RW_PMUX3 0x20c
+#define REG_RW_PMUX4 0x210
+#define REG_RW_PMUX5 0x214
+#define REG_RW_PMUX6 0x218
+#define REG_RW_PMUX7 0x21c
+#define REG_RW_PMUX8 0x220
+#define REG_RW_PMUX9 0x224
+
+
+
+#define REG_RW_GPIO_EN_1 0x128
+#define REG_RW_GPIO_OUT_1 0x11c
+#define REG_RW_GPIO_IN_1 0x138
+
+
+#define REG_RW_GPIO_EN_0 0x124 /* need get register addr */
+/* #define REG_RW_GPIO_OUT_0 0x11c // need get register addr */
+#define REG_RW_GPIO_IN_0 0x134 /* need get register addr */
+
+/* #define REG_RW_GPIO_EN_2 0x128 // need get register addr */
+/* #define REG_RW_GPIO_OUT_2 0x11c // need get register addr */
+/* #define REG_RW_GPIO_IN_2 0x138 // need get register addr */
+
+
+#define REG_RW_PLL_GPANACFG0 0x34c
+#define PLL_GPANACFG0_NFIPLL_EN (1U<<1)
+
+
+#define REG_RW_PAD_PD0 0x258
+#define REG_RW_PAD_PD1 0x25c
+#define REG_RW_PAD_PD2 0x260
+
+#define REG_RW_PAD_PU0 0x264
+#define REG_RW_PAD_PU1 0x268
+#define REG_RW_PAD_PU2 0x26c
+
+
+extern int mt8193_ckgen_i2c_write(u16 addr, u32 data);
+extern u32 mt8193_ckgen_i2c_read(u16 addr);
+
+
+#define IO_READ8(base, offset) mt8193_ckgen_i2c_read((base) + (offset))
+#define IO_READ16(base, offset) mt8193_ckgen_i2c_read((base) + (offset))
+#define IO_READ32(base, offset) mt8193_ckgen_i2c_read((base) + (offset))
+
+/*===========================================================================*/
+/* Macros for register write */
+/*===========================================================================*/
+#define IO_WRITE8(base, offset, value) mt8193_ckgen_i2c_write((base) + (offset), (value))
+#define IO_WRITE16(base, offset, value) mt8193_ckgen_i2c_write((base) + (offset), (value))
+#define IO_WRITE32(base, offset, value) mt8193_ckgen_i2c_write((base) + (offset), (value))
+
+
+#define CKGEN_READ8(offset) IO_READ8(CKGEN_BASE, (offset))
+#define CKGEN_READ16(offset) IO_READ16(CKGEN_BASE, (offset))
+#define CKGEN_READ32(offset) IO_READ32(CKGEN_BASE, (offset))
+
+#define CKGEN_WRITE8(offset, value) IO_WRITE8(CKGEN_BASE, (offset), (value))
+#define CKGEN_WRITE16(offset, value) IO_WRITE16(CKGEN_BASE, (offset), (value))
+#define CKGEN_WRITE32(offset, value) IO_WRITE32(CKGEN_BASE, (offset), (value))
+
+
+/*=======================================================================*/
+/* Constant Definitions */
+/*=======================================================================*/
+
+enum SRC_CK_T {
+ SRC_CK_APLL,
+ SRC_CK_ARMPLL,
+ SRC_CK_VDPLL,
+ SRC_CK_DMPLL,
+ SRC_CK_SYSPLL1,
+ SRC_CK_SYSPLL2,
+ SRC_CK_USBCK,
+ SRC_CK_MEMPLL,
+ SRC_CK_MCK
+};
+
+enum e_CLK_T {
+ e_CLK_NFI, /*0 0x70.3 */
+ e_CLK_HDMIPLL, /* 1 0x70.7 */
+ e_CLK_HDMIDISP,
+ e_CLK_LVDSDISP,
+ e_CLK_LVDSCTS,
+ e_CLK_MAX /* 2 */
+};
+
+enum e_CKGEN_T {
+ e_CKEN_NFI, /* 0 0x300.31 */
+ e_CKEN_HDMI, /* 1 0x300.29 */
+ e_CKEN_MAX /* 2 */
+};
+
+#define MT8193_I2C_ID 1
+#define USING_MT8193_DPI1 1
+
+#endif /* MT8193_H */
diff --git a/drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193_ckgen.h b/drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193_ckgen.h
new file mode 100644
index 000000000000..35d27099eaee
--- /dev/null
+++ b/drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193_ckgen.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef MT8193_CKGEN_H
+#define MT8193_CKGEN_H
+
+#define MT8193_CKGEN_VFY 1
+
+#define MT8193_DISABLE_DCXO 0
+
+
+#define CKGEN_IOW(num, dtype) _IOW('H', num, dtype)
+#define CKGEN_IOR(num, dtype) _IOR('H', num, dtype)
+#define CKGEN_IOWR(num, dtype) _IOWR('H', num, dtype)
+#define CKGEN_IO(num) _IO('H', num)
+
+#define MTK_MT8193_CKGEN_1 CKGEN_IO(1)
+#define MTK_MT8193_CKGEN_2 CKGEN_IO(2)
+#define MTK_MT8193_CKGEN_LS_TEST CKGEN_IO(3) /* level shift test */
+#define MTK_MT8193_CKGEN_SPM_CTRL CKGEN_IO(4) /* spm ctrl test */
+#define MTK_MT8193_CKGEN_FREQ_METER CKGEN_IO(5) /* FREQ METER TEST*/
+#define MTK_MT8193_GPIO_CTRL CKGEN_IO(6) /* GPIO CTRL*/
+#define MTK_MT8193_EARLY_SUSPEND CKGEN_IO(7) /* early suspend*/
+#define MTK_MT8193_LATE_RESUME CKGEN_IO(8) /* late resume*/
+
+#define REG_RW_FMETER 0x04c /* freq meter register */
+#define CKGEN_FMETER_RESET 1
+#define CKGEN_FMETER_START (1U<<1)
+#define CKGEN_FMETER_DONE (1U<<2)
+
+/* HDMI POWER OFF/ON CONTROL*/
+
+#define REG_RW_HDMI_PWR_RST_B 0x100
+#define CKGEN_HDMI_PWR_RST_EN 1
+
+#define REG_RW_HDMI_PWR_CTRL 0x104
+#define CKGEN_HDMI_PWR_ISO_EN 1
+#define CKGEN_HDMI_PWR_PWR_ON (1U<<1)
+#define CKGEN_HDMI_PWR_CLK_OFF (1U<<2)
+
+/* LVDS POWER OFF/ON CONTROL*/
+
+#define REG_RW_LVDS_PWR_RST_B 0x108
+#define CKGEN_LVDS_PWR_RST_EN 1
+
+#define REG_RW_LVDS_PWR_CTRL 0x10c
+#define CKGEN_LVDS_PWR_ISO_EN 1
+#define CKGEN_LVDS_PWR_PWR_ON (1U<<1)
+#define CKGEN_LVDS_PWR_CLK_OFF (1U<<2)
+
+/* NFI POWER OFF/ON CONTROL*/
+
+#define REG_RW_NFI_PWR_RST_B 0x110
+#define CKGEN_NFI_PWR_RST_EN 1
+
+#define REG_RW_NFI_PWR_CTRL 0x114
+#define CKGEN_NFI_PWR_ISO_EN 1
+#define CKGEN_NFI_PWR_PWR_ON (1U<<1)
+#define CKGEN_NFI_PWR_CLK_OFF (1U<<2)
+
+#define REG_RO_PWR_ACT 0x118
+#define CKGEN_NFI_PWR_ON_ACT 1
+#define CKGEN_LVDS_PWR_ON_ACT (1U<<1)
+#define CKGEN_HDMI_PWR_ON_ACT (1U<<2)
+
+#define REG_RW_LS_CTRL 0x012c /* level shift control */
+#define LS_CTRL_GROUP0_SHIFT_HIGH 1 /* 0: 3.3 -> 1.8; 1: 1.8->3.3 */
+#define LS_CTRL_GROUP1_SHIFT_HIGH (1U<<1) /* 0: 3.3 -> 1.8; 1: 1.8->3.3 */
+#define LS_CTRL_GROUP2_SHIFT_HIGH (1U<<2) /* 0: 3.3 -> 1.8; 1: 1.8->3.3 */
+#define LS_CTRL_GROUP3_SHIFT_HIGH (1U<<3) /* 0: 3.3 -> 1.8; 1: 1.8->3.3 */
+#define LS_CTRL_GROUP4_SHIFT_HIGH (1U<<4) /* 0: 3.3 -> 1.8; 1: 1.8->3.3 */
+#define LS_CTRL_GROUP5_SHIFT_HIGH (1U<<5) /* 0: 3.3 -> 1.8; 1: 1.8->3.3 */
+#define LS_CTRL_GROUP6_SHIFT_HIGH (1U<<6) /* 0: 3.3 -> 1.8; 1: 1.8->3.3 */
+#define LS_CTRL_SHIFT_HIGH_EN (1U<<30) /* 1.8>3.3 enable */
+#define LS_CTRL_SHIFT_LOW_EN (1U<<31) /* 3.3>1.8 enable */
+
+#define REG_RW_LVDS_ANACFG4 0x320
+#define LVDS_ANACFG4_VPlLL_PD (1U<<10)
+
+#define REG_RW_HDMITX_ANACFG3 0x334
+#define HDMITX_ANACFG3_BIT20 (1U<<20)
+#define HDMITX_ANACFG3_BIT21 (1U<<21)
+
+#define REG_RW_PLLGP_ANACFG0 0x34c
+#define PLLGP_ANACFG0_PLL1_RESERVED 1
+#define PLLGP_ANACFG0_PLL1_NFIPLL_EN (1U<<1)
+#define PLLGP_ANACFG0_PLL1_EN (1U<<31)
+
+#define REG_RW_PLLGP_ANACFG2 0x354
+#define PLLGP_ANACFG2_PLLGP_BIAS_EN (1U<<20)
+
+#define REG_RW_DCXO_ANACFG9 0x388
+#define DCXO_ANACFG9_BUS_CK_SOURCE_SEL_SHIFT 9
+#define DCXO_ANACFG9_BUS_CK_SOURCE_SEL_MASK 0x7
+#define DCX0_ANACFG9_BUS_CK_CTRL_SEL (1U<<7)
+#define DCX0_ANACFG9_BUS_CK_AUTO_SWITCH_EN (1U<<5)
+
+/* DCXO */
+
+#define REG_RW_DCXO_ANACFG2 0x308
+#define DCXO_ANACFG2_LDO4_EN (1U<<2)
+#define DCXO_ANACFG2_LDO4_MAN_EN (1U<<3)
+#define DCXO_ANACFG2_LDO3_EN (1U<<4)
+#define DCXO_ANACFG2_LDO3_MAN_EN (1U<<5)
+#define DCXO_ANACFG2_LDO2_EN (1U<<6)
+#define DCXO_ANACFG2_LDO2_MAN_EN (1U<<7)
+#define DCXO_ANACFG2_LDO1_EN (1U<<8)
+#define DCXO_ANACFG2_LDO1_MAN_EN (1U<<9)
+#define DCXO_ANACFG2_PO_MAN (1U<<29)
+
+#define REG_RW_DCXO_ANACFG4 0x370
+#define DCXO_ANACFG4_BT_MAN (1U<<18)
+#define DCXO_ANACFG4_EXT2_MAN (1U<<19)
+#define DCXO_ANACFG4_EXT1_MAN (1U<<20)
+
+#if MT8193_CKGEN_VFY
+/* level shift test parameter */
+struct mt8193_ckgen_ls_info_t {
+ int i4GroupNum;
+ int i4TurnLow;
+};
+
+/* freq meter parameter */
+struct mt8193_ckgen_freq_meter_t {
+ int u4Func;
+};
+
+/* GPIO CTRL parameter */
+struct mt8193_gpio_ctrl_t {
+ int u4GpioNum;
+ int u4Mode; /* 0 is input. 1 is output */
+ int u4Value; /* 1 is high. 0 is low. only valid in output mode */
+};
+
+#if 0
+
+/* config gpio */
+int mt8193_ckgen_gpio_config(int i4GpioNum, int i4Output, int i4High);
+
+/* print gpio input value */
+int mt8193_ckgen_gpio_input(int i4GpioNum);
+
+
+/* test pad level shift */
+int mt8193_ckgen_config_pad_level_shift(int i4GroupNum, int i4TurnLow);
+
+/* read and print chip id */
+void mt8193_ckgen_chipid(void);
+
+
+/* measure clock with freq meter */
+u32 mt8193_ckgen_measure_clk(u32 u4Func);
+
+u32 mt8193_ckgen_reg_rw_test(u16 addr);
+#endif
+
+extern int multibridge_exit;
+
+void mt8193_lvds_sys_spm_control(bool power_on);
+void mt8193_hdmi_sys_spm_control(bool power_on);
+void mt8193_nfi_sys_spm_control(bool power_on);
+void mt8193_lvds_ana_pwr_control(bool power_on);
+void mt8193_pllgp_ana_pwr_control(bool power_on);
+void mt8193_bus_clk_switch(bool bus_26m_to_32k);
+void mt8193_hdmi_ana_pwr_control(bool power_on);
+void mt8193_nfi_ana_pwr_control(bool power_on);
+int mt8193_ckgen_config_pad_level_shift(int i4GroupNum, int i4TurnLow);
+void mt8193_spm_control_test(int u4Func);
+u32 mt8193_ckgen_measure_clk(u32 u4Func);
+void mt8193_ckgen_early_suspend(void);
+void mt8193_ckgen_late_resume(void);
+
+#endif
+
+#endif /* MT8193_CKGEN_H */
diff --git a/drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193_gpio.h b/drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193_gpio.h
new file mode 100644
index 000000000000..e8408ce7807a
--- /dev/null
+++ b/drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193_gpio.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef MT8193_GPIO_H
+#define MT8193_GPIO_H
+
+#include <generated/autoconf.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/kthread.h>
+#include <linux/vmalloc.h>
+
+#include <linux/uaccess.h>
+#include <linux/atomic.h>
+#include <asm/cacheflush.h>
+#include <linux/io.h>
+
+#include <mach/irqs.h>
+
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/cdev.h>
+#include <asm/tlbflush.h>
+#include <asm/page.h>
+#include <linux/slab.h>
+
+#include <linux/module.h>
+#include "mt8193_pinmux.h"
+
+
+#define MT8193_GPIO_OUTPUT 1
+#define MT8193_GPIO_INPUT 0
+#define MT8193_GPIO_HIGH 1
+#define MT8193_GPIO_LOW 0
+
+enum MT8193_GPIO_PIN {
+ GPIO_PIN_UNSUPPORTED = -1,
+
+ GPIO_PIN_GPIO0,
+ GPIO_PIN_GPIO1,
+ GPIO_PIN_GPIO2,
+ GPIO_PIN_GPIO3,
+ GPIO_PIN_GPIO4,
+ GPIO_PIN_GPIO5,
+ GPIO_PIN_GPIO6,
+ GPIO_PIN_GPIO7,
+ GPIO_PIN_GPIO8,
+ GPIO_PIN_GPIO9,
+ GPIO_PIN_GPIO10,
+ GPIO_PIN_GPIO11,
+ GPIO_PIN_GPIO12,
+ GPIO_PIN_GPIO13,
+ GPIO_PIN_GPIO14,
+ GPIO_PIN_GPIO15,
+ GPIO_PIN_GPIO16,
+ GPIO_PIN_GPIO17,
+ GPIO_PIN_GPIO18,
+ GPIO_PIN_GPIO19,
+ GPIO_PIN_GPIO20,
+ GPIO_PIN_GPIO21,
+ GPIO_PIN_GPIO22,
+ GPIO_PIN_GPIO23,
+ GPIO_PIN_GPIO24,
+ GPIO_PIN_GPIO25,
+ GPIO_PIN_GPIO26,
+ GPIO_PIN_GPIO27,
+ GPIO_PIN_GPIO28,
+ GPIO_PIN_GPIO29,
+ GPIO_PIN_GPIO30,
+ GPIO_PIN_GPIO31,
+ GPIO_PIN_GPIO32,
+ GPIO_PIN_GPIO33,
+ GPIO_PIN_GPIO34,
+ GPIO_PIN_GPIO35,
+ GPIO_PIN_GPIO36,
+ GPIO_PIN_GPIO37,
+ GPIO_PIN_GPIO38,
+ GPIO_PIN_GPIO39,
+ GPIO_PIN_GPIO40,
+ GPIO_PIN_GPIO41,
+ GPIO_PIN_GPIO42,
+ GPIO_PIN_GPIO43,
+ GPIO_PIN_GPIO44,
+ GPIO_PIN_GPIO45,
+ GPIO_PIN_GPIO46,
+ GPIO_PIN_GPIO47,
+ GPIO_PIN_GPIO48,
+ GPIO_PIN_GPIO49,
+ GPIO_PIN_GPIO50,
+ GPIO_PIN_GPIO51,
+ GPIO_PIN_GPIO52,
+ GPIO_PIN_GPIO53,
+ GPIO_PIN_GPIO54,
+ GPIO_PIN_GPIO55,
+ GPIO_PIN_GPIO56,
+ GPIO_PIN_GPIO57,
+ GPIO_PIN_GPIO58,
+ GPIO_PIN_GPIO59,
+ GPIO_PIN_GPIO60,
+ GPIO_PIN_GPIO61,
+ GPIO_PIN_GPIO62,
+ GPIO_PIN_GPIO63,
+ GPIO_PIN_GPIO64,
+ GPIO_PIN_GPIO65,
+ GPIO_PIN_GPIO66,
+ GPIO_PIN_GPIO67,
+ GPIO_PIN_GPIO68,
+ GPIO_PIN_GPIO69,
+ GPIO_PIN_GPIO70,
+ GPIO_PIN_GPIO71,
+
+ GPIO_PIN_MAX
+};
+
+
+/* _au4GpioTbl[gpio num] is pad num */
+static const u32 _au4GpioTbl[GPIO_PIN_MAX] = {
+ PIN_NFD6, /* gpio0 */
+ PIN_NFD5,
+ PIN_NFD4,
+ PIN_NFD3,
+ PIN_NFD2,
+ PIN_NFD1,
+ PIN_NFD0, /* gpio6 */
+ PIN_G0, /* gpio 7 */
+ PIN_B5,
+ PIN_B4,
+ PIN_B3,
+ PIN_B2,
+ PIN_B1,
+ PIN_B0,
+ PIN_DE,
+ PIN_VCLK,
+ PIN_HSYNC,
+ PIN_VSYNC,
+ PIN_CEC,
+ PIN_HDMISCK,
+ PIN_HDMISD,
+ PIN_HTPLG,
+ PIN_I2S_DATA,
+ PIN_I2S_LRCK,
+ PIN_I2S_BCK,
+ PIN_DPI1CK,
+ PIN_DPI1D7,
+ PIN_DPI1D6,
+ PIN_DPI1D5,
+ PIN_DPI1D4,
+ PIN_DPI1D3,
+ PIN_DPI1D2,
+ PIN_DPI1D1,
+ PIN_DPI1D0,
+ PIN_DPI0CK,
+ PIN_DPI0HSYNC,
+ PIN_DPI0VSYNC,
+ PIN_DPI0D11,
+ PIN_DPI0D10,
+ PIN_DPI0D9,
+ PIN_DPI0D8,
+ PIN_DPI0D7,
+ PIN_DPI0D6,
+ PIN_DPI0D5,
+ PIN_DPI0D4,
+ PIN_DPI0D3,
+ PIN_DPI0D2,
+ PIN_DPI0D1,
+ PIN_DPI0D0,
+ PIN_SDA,
+ PIN_SCL,
+ PIN_NRNB,
+ PIN_NCLE,
+ PIN_NALE,
+ PIN_NWEB,
+ PIN_NREB,
+ PIN_NLD7,
+ PIN_NLD6,
+ PIN_NLD5,
+ PIN_NLD4,
+ PIN_NLD3,
+ PIN_NLD2,
+ PIN_NLD1,
+ PIN_NLD0, /* gpio 63 */
+ PIN_INT, /* gpio 64*/
+ PIN_NFRBN, /* gpio 65*/
+ PIN_NFCLE,
+ PIN_NFALE,
+ PIN_NFWEN,
+ PIN_NFREN,
+ PIN_NFCEN,
+ PIN_NFD7, /* gpio 71 */
+};
+
+extern int GPIO_Config(u32 u4GpioNum, u8 u1Mode, u8 u1Value);
+extern u8 GPIO_Input(u32 i4GpioNum);
+extern int GPIO_Output(u32 u4GpioNum, u32 u4High);
+
+#endif /* MT8193_H */
diff --git a/drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193_iic.h b/drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193_iic.h
new file mode 100644
index 000000000000..4deb6524082e
--- /dev/null
+++ b/drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193_iic.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef MT8193_IIC_H
+#define MT8193_IIC_H
+
+/*----------------------------------------------------------------------------*/
+/* IIC APIs */
+/*----------------------------------------------------------------------------*/
+int mt8193_i2c_read(u16 addr, u32 *data);
+int mt8193_i2c_write(u16 addr, u32 data);
+
+#endif /* MT8193_IIC_H */
+
diff --git a/drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193_pinmux.h b/drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193_pinmux.h
new file mode 100644
index 000000000000..897fd347c4ec
--- /dev/null
+++ b/drivers/misc/mediatek/multibridge/mt6797/mt8193/inc/mt8193_pinmux.h
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef MT8193_PINMUX_H
+#define MT8193_PINMUX_H
+
+
+#include <generated/autoconf.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/kthread.h>
+#include <linux/vmalloc.h>
+
+#include <linux/uaccess.h>
+#include <linux/atomic.h>
+#include <asm/cacheflush.h>
+#include <linux/io.h>
+
+#include <mach/irqs.h>
+
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/cdev.h>
+#include <asm/tlbflush.h>
+#include <asm/page.h>
+#include <linux/slab.h>
+
+#include <linux/module.h>
+
+#include "mt8193.h"
+
+
+/* ret code */
+
+#define PINMUX_RET_OK 0
+#define PINMUX_RET_INVALID_ARG (-1)
+#define PINMUX_RET_FAIL (-2)
+
+
+
+#define PINMUX_FUNCTION0 0
+#define PINMUX_FUNCTION1 1
+#define PINMUX_FUNCTION2 2
+#define PINMUX_FUNCTION3 3
+#define PINMUX_FUNCTION4 4
+#define PINMUX_FUNCTION5 5
+#define PINMUX_FUNCTION6 6
+#define PINMUX_FUNCTION7 7
+#define PINMUX_FUNCTION_MAX 8
+
+enum MT8193_APD_PIN {
+ PIN_UNSUPPORTED = -1,
+
+ PIN_NFD6,
+ PIN_NFD5,
+ PIN_NFD4,
+ PIN_NFD3,
+ PIN_NFD2,
+ PIN_NFD1,
+ PIN_NFD0,
+ PIN_TP_VPLL,
+ PIN_AO0N,
+ PIN_AO0P,
+ PIN_AO1N,
+ PIN_AO1P,
+ PIN_AO2N,
+ PIN_AO2P,
+ PIN_AOCK0N,
+ PIN_AOCK0P,
+ PIN_AO3N,
+ PIN_AO3P,
+ PIN_G0,
+ PIN_B5,
+ PIN_B4,
+ PIN_B3,
+ PIN_B2,
+ PIN_B1,
+ PIN_B0,
+ PIN_DE,
+ PIN_VCLK,
+ PIN_HSYNC,
+ PIN_VSYNC,
+ PIN_CEC,
+ PIN_HDMISCK,
+ PIN_HDMISD,
+ PIN_HTPLG,
+ PIN_I2S_DATA,
+ PIN_I2S_LRCK,
+ PIN_I2S_BCK,
+ PIN_DPI1CK,
+ PIN_DPI1D7,
+ PIN_DPI1D6,
+ PIN_DPI1D5,
+ PIN_DPI1D4,
+ PIN_DPI1D3,
+ PIN_DPI1D2,
+ PIN_DPI1D1,
+ PIN_DPI1D0,
+ PIN_DPI0CK,
+ PIN_DPI0HSYNC,
+ PIN_DPI0VSYNC,
+ PIN_DPI0D11,
+ PIN_DPI0D10,
+ PIN_DPI0D9,
+ PIN_DPI0D8,
+ PIN_DPI0D7,
+ PIN_DPI0D6,
+ PIN_DPI0D5,
+ PIN_DPI0D4,
+ PIN_DPI0D3,
+ PIN_DPI0D2,
+ PIN_DPI0D1,
+ PIN_DPI0D0,
+ PIN_SDA,
+ PIN_SCL,
+ PIN_NRNB,
+ PIN_NCLE,
+ PIN_NALE,
+ PIN_NWEB,
+ PIN_NREB,
+ PIN_NLD7,
+ PIN_NLD6,
+ PIN_NLD5,
+ PIN_NLD4,
+ PIN_NLD3,
+ PIN_NLD2,
+ PIN_NLD1,
+ PIN_NLD0,
+ PIN_RTC_32K_CK,
+ PIN_INT,
+ PIN_RESET,
+ PIN_EN_BB,
+ PIN_CK_SEL,
+ PIN_NFRBN,
+ PIN_NFCLE,
+ PIN_NFALE,
+ PIN_NFWEN,
+ PIN_NFREN,
+ PIN_NFCEN,
+ PIN_NFD7,
+ PIN_PROT0,
+ PIN_PROT1,
+ PIN_PROT2,
+ PIN_PROT3,
+ PIN_PROT4,
+ PIN_PROT5,
+
+ PIN_MAX
+};
+
+
+/*
+function table
+
+[pin][2 * function]
+
+pin0: func_pmux, func_sel (<<), func_mask
+pin1: func_pmux, func_sel, func_mask
+pin2: func_pmux, func_sel, func_mask
+*/
+static const u32 _au4PinmuxFuncTbl[PIN_MAX][3] = {
+ /* PIN_NFD6, */ {REG_RW_PMUX1, 0, 0x7},
+ /* PIN_NFD5, */ {REG_RW_PMUX1, 3, 0x38},
+ /* PIN_NFD4, */ {REG_RW_PMUX1, 6, 0x1C0},
+ /* PIN_NFD3, */ {REG_RW_PMUX1, 9, 0xE00},
+ /* PIN_NFD2, */ {REG_RW_PMUX1, 12, 0x7000},
+ /* PIN_NFD1, */ {REG_RW_PMUX1, 15, 0x38000},
+ /* PIN_NFD0, */ {REG_RW_PMUX1, 18, 0x1C0000},
+ /* PIN_TP_VPLL, */ {REG_RW_PMUX8, 18, 0x1C0000},
+ /* PIN_AO0N, */ {REG_RW_PMUX8, 21, 0xE00000},
+ /* PIN_AO0P, */ {REG_RW_PMUX8, 24, 0x7000000},
+ /* PIN_AO1N, */ {REG_RW_PMUX8, 27, 0x38000000},
+ /* PIN_AO1P, */ {REG_RW_PMUX9, 0, 0x7},
+ /* PIN_AO2N, */ {REG_RW_PMUX9, 3, 0x38},
+ /* PIN_AO2P, */ {REG_RW_PMUX9, 6, 0x1C0},
+ /* PIN_AOCK0N, */ {REG_RW_PMUX9, 9, 0xE00},
+ /* PIN_AOCK0P, */ {REG_RW_PMUX9, 12, 0x7000},
+ /* PIN_AO3N, */ {REG_RW_PMUX9, 15, 0x38000},
+ /* PIN_AO3P, */ {REG_RW_PMUX9, 18, 0x1C0000},
+ /* PIN_G0, */ {REG_RW_PMUX1, 21, 0xE00000},
+ /* PIN_B5, */ {REG_RW_PMUX1, 24, 0x7000000},
+ /* PIN_B4, */ {REG_RW_PMUX1, 27, 0x38000000},
+ /* PIN_B3, */ {REG_RW_PMUX2, 0, 0x7},
+ /* PIN_B2, */ {REG_RW_PMUX2, 3, 0x38},
+ /* PIN_B1, */ {REG_RW_PMUX2, 6, 0x1C0},
+ /* PIN_B0, */ {REG_RW_PMUX2, 9, 0xE00},
+ /* PIN_DE, */ {REG_RW_PMUX2, 12, 0x7000},
+ /* PIN_VCLK, */ {REG_RW_PMUX2, 15, 0x38000},
+ /* PIN_HSYNC, */ {REG_RW_PMUX2, 18, 0x1C0000},
+ /* PIN_VSYNC, */ {REG_RW_PMUX2, 21, 0xE00000},
+ /* PIN_CEC, */ {REG_RW_PMUX2, 24, 0x7000000},
+ /* PIN_HDMISCK, */ {REG_RW_PMUX2, 27, 0x38000000},
+ /* PIN_HDMISD, */ {REG_RW_PMUX3, 0, 0x7},
+ /* PIN_HTPLG, */ {REG_RW_PMUX3, 3, 0x38},
+ /* PIN_I2S_DATA, */ {REG_RW_PMUX3, 6, 0x1C0},
+ /* PIN_I2S_LRCK, */ {REG_RW_PMUX3, 9, 0xE00},
+ /* PIN_I2S_BCK, */ {REG_RW_PMUX3, 12, 0x7000},
+ /* PIN_DPI1CK, */ {REG_RW_PMUX3, 15, 0x38000},
+ /* PIN_DPI1D7, */ {REG_RW_PMUX3, 18, 0x1C0000},
+ /* PIN_DPI1D6, */ {REG_RW_PMUX3, 21, 0xE00000},
+ /* PIN_DPI1D5, */ {REG_RW_PMUX3, 24, 0x7000000},
+ /* PIN_DPI1D4, */ {REG_RW_PMUX3, 27, 0x38000000},
+ /* PIN_DPI1D3, */ {REG_RW_PMUX4, 0, 0x7},
+ /* PIN_DPI1D2, */ {REG_RW_PMUX4, 3, 0x38},
+ /* PIN_DPI1D1, */ {REG_RW_PMUX4, 6, 0x1C0},
+ /* PIN_DPI1D0, */ {REG_RW_PMUX4, 9, 0xE00},
+ /* PIN_DPI0CK, */ {REG_RW_PMUX4, 12, 0x7000},
+ /* PIN_DPI0HSYNC, */ {REG_RW_PMUX4, 15, 0x38000},
+ /* PIN_DPI0VSYNC, */ {REG_RW_PMUX4, 18, 0x1C0000},
+ /* PIN_DPI0D11, */ {REG_RW_PMUX4, 21, 0xE00000},
+ /* PIN_DPI0D10, */ {REG_RW_PMUX4, 24, 0x7000000},
+ /* PIN_DPI0D9, */ {REG_RW_PMUX4, 27, 0x38000000},
+ /* PIN_DPI0D8, */ {REG_RW_PMUX5, 0, 0x7},
+ /* PIN_DPI0D7, */ {REG_RW_PMUX5, 3, 0x38},
+ /* PIN_DPI0D6, */ {REG_RW_PMUX5, 6, 0x1C0},
+ /* PIN_DPI0D5, */ {REG_RW_PMUX5, 9, 0xE00},
+ /* PIN_DPI0D4, */ {REG_RW_PMUX5, 12, 0x7000},
+ /* PIN_DPI0D3, */ {REG_RW_PMUX5, 15, 0x38000},
+ /* PIN_DPI0D2, */ {REG_RW_PMUX5, 18, 0x1C0000},
+ /* PIN_DPI0D1, */ {REG_RW_PMUX5, 21, 0xE00000},
+ /* PIN_DPI0D0, */ {REG_RW_PMUX5, 24, 0x7000000},
+ /* PIN_SDA, */ {REG_RW_PMUX5, 27, 0x38000000},
+ /* PIN_SCL, */ {REG_RW_PMUX6, 0, 0x7},
+ /* PIN_NRNB, */ {REG_RW_PMUX6, 3, 0x38},
+ /* PIN_NCLE, */ {REG_RW_PMUX6, 6, 0x1C0},
+ /* PIN_NALE, */ {REG_RW_PMUX6, 9, 0xE00},
+ /* PIN_NWEB, */ {REG_RW_PMUX6, 12, 0x7000},
+ /* PIN_NREB, */ {REG_RW_PMUX6, 15, 0x38000},
+ /* PIN_NLD7, */ {REG_RW_PMUX6, 18, 0x1C0000},
+ /* PIN_NLD6, */ {REG_RW_PMUX6, 21, 0xE00000},
+ /* PIN_NLD5, */ {REG_RW_PMUX6, 24, 0x7000000},
+ /* PIN_NLD4, */ {REG_RW_PMUX6, 27, 0x38000000},
+ /* PIN_NLD3, */ {REG_RW_PMUX7, 0, 0x7},
+ /* PIN_NLD2, */ {REG_RW_PMUX7, 3, 0x38},
+ /* PIN_NLD1, */ {REG_RW_PMUX7, 6, 0x1C0},
+ /* PIN_NLD0, */ {REG_RW_PMUX7, 9, 0xE00},
+ /* PIN_RTC_32K_CK, */ {REG_RW_PMUX7, 12, 0x7000},
+ /* PIN_INT, */ {REG_RW_PMUX7, 15, 0x38000},
+ /* PIN_RESET, */ {REG_RW_PMUX7, 18, 0x1C0000},
+ /* PIN_EN_BB, */ {REG_RW_PMUX7, 21, 0xE00000},
+ /* PIN_CK_SEL, */ {REG_RW_PMUX7, 24, 0x7000000},
+ /* PIN_NFRBN, */ {REG_RW_PMUX7, 27, 0x38000000},
+ /* PIN_NFCLE, */ {REG_RW_PMUX8, 0, 0x7},
+ /* PIN_NFALE, */ {REG_RW_PMUX8, 3, 0x38},
+ /* PIN_NFWEN, */ {REG_RW_PMUX8, 6, 0x1C0},
+ /* PIN_NFREN, */ {REG_RW_PMUX8, 9, 0xE00},
+ /* PIN_NFCEN, */ {REG_RW_PMUX8, 12, 0x7000},
+ /* PIN_NFD7, */ {REG_RW_PMUX8, 15, 0x38000},
+ /* PIN_PROT0, */ {REG_RW_PMUX9, 21, 0x100000},
+ /* PIN_PROT1, */ {REG_RW_PMUX9, 22, 0x200000},
+ /* PIN_PROT2, */ {REG_RW_PMUX9, 23, 0x400000},
+ /* PIN_PROT3, */ {REG_RW_PMUX9, 24, 0x800000},
+ /* PIN_PROT4, */ {REG_RW_PMUX9, 25, 0x1000000},
+ /* PIN_PROT5, */ {REG_RW_PMUX9, 26, 0x2000000},
+};
+
+/* pu shift, pd shift*/
+static const u32 _au4PinmuxPadPuPdTbl[PIN_MAX][2] = {
+ /* PIN_NFD6, */ {0, 0},
+ /* PIN_NFD5, */ {1, 1},
+ /* PIN_NFD4, */ {2, 2},
+ /* PIN_NFD3, */ {3, 3},
+ /* PIN_NFD2, */ {4, 4},
+ /* PIN_NFD1, */ {5, 5},
+ /* PIN_NFD0, */ {6, 6},
+ /* PIN_TP_VPLL, */ {0, 0},
+ /* PIN_AO0N, */ {0, 0},
+ /* PIN_AO0P, */ {0, 0},
+ /* PIN_AO1N, */ {0, 0},
+ /* PIN_AO1P, */ {0, 0},
+ /* PIN_AO2N, */ {0, 0},
+ /* PIN_AO2P, */ {0, 0},
+ /* PIN_AOCK0N, */ {0, 0},
+ /* PIN_AOCK0P, */ {0, 0},
+ /* PIN_AO3N, */ {0, 0},
+ /* PIN_AO3P, */ {0, 0},
+ /* PIN_G0, */ {7, 7},
+ /* PIN_B5, */ {8, 8},
+ /* PIN_B4, */ {9, 9},
+ /* PIN_B3, */ {10, 10},
+ /* PIN_B2, */ {11, 11},
+ /* PIN_B1, */ {12, 12},
+ /* PIN_B0, */ {13, 13},
+ /* PIN_DE, */ {14, 14},
+ /* PIN_VCLK, */ {17, 17},
+ /* PIN_HSYNC, */ {16, 16},
+ /* PIN_VSYNC, */ {15, 15},
+ /* PIN_CEC, */ {0, 0},
+ /* PIN_HDMISCK, */ {19, 19},
+ /* PIN_HDMISD, */ {20, 20},
+ /* PIN_HTPLG, */ {21, 21},
+ /* PIN_I2S_DATA, */ {22, 22},
+ /* PIN_I2S_LRCK, */ {23, 23},
+ /* PIN_I2S_BCK, */ {24, 24},
+ /* PIN_DPI1CK, */ {25, 25},
+ /* PIN_DPI1D7, */ {26, 26},
+ /* PIN_DPI1D6, */ {27, 27},
+ /* PIN_DPI1D5, */ {28, 28},
+ /* PIN_DPI1D4, */ {29, 29},
+ /* PIN_DPI1D3, */ {30, 30},
+ /* PIN_DPI1D2, */ {31, 31},
+ /* PIN_DPI1D1, */ {32, 32},
+ /* PIN_DPI1D0, */ {33, 33},
+ /* PIN_DPI0CK, */ {34, 34},
+ /* PIN_DPI0HSYNC, */ {35, 35},
+ /* PIN_DPI0VSYNC, */ {36, 36},
+ /* PIN_DPI0D11, */ {37, 37},
+ /* PIN_DPI0D10, */ {38, 38},
+ /* PIN_DPI0D9, */ {39, 39},
+ /* PIN_DPI0D8, */ {40, 40},
+ /* PIN_DPI0D7, */ {41, 41},
+ /* PIN_DPI0D6, */ {42, 42},
+ /* PIN_DPI0D5, */ {43, 43},
+ /* PIN_DPI0D4, */ {44, 44},
+ /* PIN_DPI0D3, */ {45, 45},
+ /* PIN_DPI0D2, */ {46, 46},
+ /* PIN_DPI0D1, */ {47, 47},
+ /* PIN_DPI0D0, */ {48, 48},
+ /* PIN_SDA, */ {49, 49},
+ /* PIN_SCL, */ {50, 50},
+ /* PIN_NRNB, */ {51, 51},
+ /* PIN_NCLE, */ {52, 52},
+ /* PIN_NALE, */ {53, 53},
+ /* PIN_NWEB, */ {54, 54},
+ /* PIN_NREB, */ {55, 55},
+ /* PIN_NLD7, */ {56, 56},
+ /* PIN_NLD6, */ {57, 57},
+ /* PIN_NLD5, */ {58, 58},
+ /* PIN_NLD4, */ {59, 59},
+ /* PIN_NLD3, */ {60, 60},
+ /* PIN_NLD2, */ {61, 16},
+ /* PIN_NLD1, */ {62, 62},
+ /* PIN_NLD0, */ {63, 63},
+ /* PIN_RTC_32K_CK, */ {0, 0},
+ /* PIN_INT, */ {64, 64},
+ /* PIN_RESET, */ {0, 0},
+ /* PIN_EN_BB, */ {0, 0},
+ /* PIN_CK_SEL, */ {0, 0},
+ /* PIN_NFRBN, */ {0, 0},
+ /* PIN_NFCLE, */ {0, 0},
+ /* PIN_NFALE, */ {0, 0},
+ /* PIN_NFWEN, */ {0, 0},
+ /* PIN_NFREN, */ {0, 0},
+ /* PIN_NFCEN, */ {0, 0},
+ /* PIN_NFD7, */ {0, 0},
+ /* PIN_PROT0, */ {0, 0},
+ /* PIN_PROT1, */ {0, 0},
+ /* PIN_PROT2, */ {0, 0},
+ /* PIN_PROT3, */ {0, 0},
+ /* PIN_PROT4, */ {0, 0},
+ /* PIN_PROT5, */ {0, 0},
+};
+
+extern int mt8193_pinset(u32 pin_num, u32 function);
+
+#endif /* MT8193_H */
diff --git a/drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_ckgen.c b/drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_ckgen.c
new file mode 100644
index 000000000000..abadd3f1a476
--- /dev/null
+++ b/drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_ckgen.c
@@ -0,0 +1,1097 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#define pr_fmt(fmt) "mt8193-ckgen: " fmt
+#define DEBUG 1
+
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include <linux/uaccess.h>
+#include <linux/delay.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#ifdef CONFIG_PM_AUTOSLEEP
+#include <linux/fb.h>
+#include <linux/notifier.h>
+#endif
+#include "mt8193.h"
+#include "mt8193_ckgen.h"
+#include "mt8193_gpio.h"
+
+
+#define MT8193_MLC 0
+#define MT8193_CKGEN_VFY 1
+#define MT8193_CKGEN_DEVNAME "mt8193-ckgen"
+
+static int mt8193_ckgen_probe(struct platform_device *pdev);
+static int mt8193_ckgen_suspend(struct platform_device *pdev, pm_message_t state);
+static int mt8193_ckgen_resume(struct platform_device *pdev);
+static int mt8193_ckgen_remove(struct platform_device *pdev);
+static void mt8193_ckgen_shutdown(struct platform_device *pdev);
+
+/******************************************************************************
+Device driver structure
+******************************************************************************/
+#ifdef CONFIG_OF
+static const struct of_device_id mt8193ckgen_of_ids[] = {
+ {.compatible = "mediatek,mt8193-ckgen",},
+ {}
+};
+#endif
+
+static struct platform_driver mt8193_ckgen_driver = {
+ .probe = mt8193_ckgen_probe,
+ .remove = mt8193_ckgen_remove,
+ .shutdown = mt8193_ckgen_shutdown,
+ .suspend = mt8193_ckgen_suspend,
+ .resume = mt8193_ckgen_resume,
+ .driver = {
+ .name = "mt8193-ckgen",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_OF
+ .of_match_table = mt8193ckgen_of_ids,
+#endif
+ },
+};
+
+static struct class *ckgen_class;
+static struct cdev *ckgen_cdev;
+
+static struct pinctrl *pinctrl;
+static struct pinctrl_state *pins_gpio;
+static struct pinctrl_state *pins_dpi;
+
+int multibridge_exit = 0;
+
+#if MT8193_CKGEN_VFY
+
+static int mt8193_ckgen_release(struct inode *inode, struct file *file);
+static int mt8193_ckgen_open(struct inode *inode, struct file *file);
+static long mt8193_ckgen_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+
+static const struct file_operations mt8193_ckgen_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = mt8193_ckgen_ioctl,
+ .open = mt8193_ckgen_open,
+ .release = mt8193_ckgen_release,
+};
+#endif
+
+void mt8193_ckgen_early_suspend(void)
+{
+ pr_err("[CKGEN] mt8193_ckgen_early_suspend() enter\n");
+
+#if !MT8193_MLC
+
+ /* If we use 8193 NFI, we should turn off pllgp in suspend because early suspend state may still use NFI.
+ Otherwise, we can turn off pllgp in early suspend. */
+
+ mt8193_pllgp_ana_pwr_control(false);
+ msleep(20);
+
+ mt8193_nfi_ana_pwr_control(false);
+
+ /* bus clk switch to 32K */
+ mt8193_bus_clk_switch(true);
+ msleep(50);
+
+#if MT8193_DISABLE_DCXO
+ mt8193_disable_dcxo_core();
+#endif
+
+#endif
+
+ pr_debug("[CKGEN] mt8193_ckgen_early_suspend() exit\n");
+}
+
+void mt8193_ckgen_late_resume(void)
+{
+ pr_err("[CKGEN] mt8193_ckgen_late_resume() enter\n");
+
+#if !MT8193_MLC
+
+ /* If we use 8193 NFI, we should turn off pllgp in suspend because early suspend state may still use NFI.
+ Otherwise, we can turn off pllgp in early suspend. */
+
+#if MT8193_DISABLE_DCXO
+ mt8193_enable_dcxo_core();
+ msleep(20);
+#endif
+
+ mt8193_bus_clk_switch(false);
+ msleep(20);
+
+ mt8193_nfi_ana_pwr_control(true);
+
+ /* turn on pllgp analog */
+ mt8193_pllgp_ana_pwr_control(true);
+ msleep(20);
+#endif
+
+ pr_debug("[CKGEN] mt8193_ckgen_late_resume() exit\n");
+}
+
+#if defined(CONFIG_HAS_EARLYSUSPEND)
+static struct early_suspend mt8193_ckgen_early_suspend_desc = {
+ .level = 0xFF,
+ .suspend = mt8193_ckgen_early_suspend,
+ .resume = mt8193_ckgen_late_resume,
+};
+#endif
+#if 0
+#ifdef CONFIG_PM_AUTOSLEEP
+static int mt8193_ckgen_fb_notifier_callback(struct notifier_block *self, unsigned long event, void *fb_evdata)
+{
+ struct fb_event *evdata = fb_evdata;
+ int blank;
+
+ if (event != FB_EVENT_BLANK)
+ return 0;
+
+ blank = *(int *)evdata->data;
+
+ switch (blank) {
+ case FB_BLANK_UNBLANK:
+ case FB_BLANK_NORMAL:
+ mt8193_ckgen_late_resume();
+ break;
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ break;
+ case FB_BLANK_POWERDOWN:
+ mt8193_ckgen_early_suspend();
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct notifier_block mt8193ckgen_fb_notif = {
+ .notifier_call = mt8193_ckgen_fb_notifier_callback,
+};
+#endif
+#endif
+
+#if MT8193_CKGEN_VFY
+static int mt8193_ckgen_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static int mt8193_ckgen_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static char *_mt8193_ckgen_ioctl_spy(unsigned int cmd)
+{
+ switch (cmd) {
+ case MTK_MT8193_CKGEN_1:
+ return "MTK_MT8193_CKGEN_1";
+ case MTK_MT8193_CKGEN_2:
+ return "MTK_MT8193_CKGEN_2";
+ case MTK_MT8193_CKGEN_SPM_CTRL:
+ return "MTK_MT8193_CKGEN_SPM_CTRL";
+ case MTK_MT8193_CKGEN_LS_TEST:
+ return "MTK_MT8193_CKGEN_LS_TEST";
+ case MTK_MT8193_CKGEN_FREQ_METER:
+ return "MTK_MT8193_CKGEN_FREQ_METER";
+ default:
+ return "unknown ioctl command";
+ }
+}
+
+static long mt8193_ckgen_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int r = 0;
+
+ pr_debug("[CKGEN] cmd=%s, arg=0x%08lx\n", _mt8193_ckgen_ioctl_spy(cmd), arg);
+
+ switch (cmd) {
+ case MTK_MT8193_CKGEN_1:
+ break;
+ case MTK_MT8193_CKGEN_2:
+ break;
+ case MTK_MT8193_CKGEN_LS_TEST:
+ {
+ struct mt8193_ckgen_ls_info_t tLsInfo;
+
+ if (copy_from_user(&tLsInfo, (void __user *)arg, sizeof(tLsInfo))) {
+ pr_err("[CKGEN] copy_from_user fails!!\n");
+ return -1;
+ }
+
+ r = mt8193_ckgen_config_pad_level_shift(tLsInfo.i4GroupNum, tLsInfo.i4TurnLow);
+
+ break;
+ }
+ case MTK_MT8193_CKGEN_SPM_CTRL:
+ {
+ int u4Func = 0;
+
+ u4Func = arg;
+ mt8193_spm_control_test(u4Func);
+ break;
+ }
+
+ case MTK_MT8193_CKGEN_FREQ_METER:
+ {
+ struct mt8193_ckgen_freq_meter_t t_freq;
+ u32 u4Clk = 0;
+
+ if (copy_from_user(&t_freq, (void __user *)arg, sizeof(t_freq))) {
+ pr_err("[CKGEN] copy_from_user fails!!\n");
+ return -1;
+ }
+
+ u4Clk = mt8193_ckgen_measure_clk(t_freq.u4Func);
+ break;
+ }
+ case MTK_MT8193_GPIO_CTRL:
+ {
+ struct mt8193_gpio_ctrl_t t_gpio;
+ u32 u4Val = 0;
+
+ if (copy_from_user(&t_gpio, (void __user *)arg, sizeof(t_gpio))) {
+ pr_err("[CKGEN] copy_from_user fails!!\n");
+ return -1;
+ }
+
+ if (t_gpio.u4Mode == MT8193_GPIO_OUTPUT) {
+ GPIO_Output(t_gpio.u4GpioNum, t_gpio.u4Value);
+ } else {
+ GPIO_Config(t_gpio.u4GpioNum, MT8193_GPIO_INPUT, 0);
+ u4Val = GPIO_Input(t_gpio.u4GpioNum);
+ pr_debug("[CKGEN] GPIO INPUT VALUE IS %d\n", u4Val);
+ }
+
+ break;
+ }
+ case MTK_MT8193_EARLY_SUSPEND:
+ break;
+ case MTK_MT8193_LATE_RESUME:
+ break;
+ default:
+ pr_err("[CKGEN] arguments error\n");
+ break;
+ }
+
+ return r;
+}
+
+#endif
+
+/******************************************************************************
+ * mt8193_ckgen_init
+ *
+ * DESCRIPTION:
+ * Init the device driver !
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None
+ *
+ * NOTES:
+ * None
+ *
+ ******************************************************************************/
+static int __init mt8193_ckgen_init(void)
+{
+ int ret = 0;
+
+
+ pr_debug("[CKGEN] mt8193_ckgen_init() enter\n");
+ ret = platform_driver_register(&mt8193_ckgen_driver);
+ if (ret) {
+ pr_err("fail to register 8193ckgen driver, ret=%d\n", ret);
+ return ret;
+ }
+
+#if defined(CONFIG_HAS_EARLYSUSPEND)
+ register_early_suspend(&mt8193_ckgen_early_suspend_desc);
+#endif
+
+#if 0
+#ifdef CONFIG_PM_AUTOSLEEP
+ ret = fb_register_client(&mt8193ckgen_fb_notif);
+ if (ret) {
+ pr_err("fail to register fb notifier, ret=%d\n", ret);
+ return ret;
+ }
+#endif
+#endif
+ pr_debug("[CKGEN] mt8193_ckgen_init() exit\n");
+
+ return 0;
+}
+
+/******************************************************************************
+ * mt8193_ckgen_exit
+ *
+ * DESCRIPTION:
+ * Free the device driver !
+ *
+ * PARAMETERS:
+ * None
+ *
+ * RETURNS:
+ * None
+ *
+ * NOTES:
+ * None
+ *
+ ******************************************************************************/
+static void __exit mt8193_ckgen_exit(void)
+{
+ devm_pinctrl_put(pinctrl);
+ platform_driver_unregister(&mt8193_ckgen_driver);
+#if defined(CONFIG_HAS_EARLYSUSPEND)
+ unregister_early_suspend(&mt8193_ckgen_early_suspend_desc);
+#endif
+}
+
+static dev_t mt8193_ckgen_devno;
+static struct cdev *mt8193_ckgen_cdev;
+
+/******************************************************************************
+ * mt8193_ckgen_probe
+ *
+ * DESCRIPTION:
+ * register the nand device file operations !
+ *
+ * PARAMETERS:
+ * struct platform_device *pdev : device structure
+ *
+ * RETURNS:
+ * 0 : Success
+ *
+ * NOTES:
+ * None
+ *
+ ******************************************************************************/
+static int mt8193_ckgen_probe(struct platform_device *pdev)
+{
+#if MT8193_CKGEN_VFY
+ int ret = 0;
+
+ pr_err("[CKGEN] %s\n", __func__);
+ /* Allocate device number for hdmi driver */
+ ret = alloc_chrdev_region(&mt8193_ckgen_devno, 0, 1, MT8193_CKGEN_DEVNAME);
+ if (ret) {
+ pr_err("[CKGEN] alloc_chrdev_region fail\n");
+ return -1;
+ }
+
+ /* For character driver register to system, device number binded to file operations */
+ mt8193_ckgen_cdev = cdev_alloc();
+ mt8193_ckgen_cdev->owner = THIS_MODULE;
+ mt8193_ckgen_cdev->ops = &mt8193_ckgen_fops;
+ ret = cdev_add(mt8193_ckgen_cdev, mt8193_ckgen_devno, 1);
+
+ /* For device number binded to device name(hdmitx), one class is corresponeded to one node */
+ ckgen_class = class_create(THIS_MODULE, MT8193_CKGEN_DEVNAME);
+ /* mknod /dev/hdmitx */
+ ckgen_cdev = (struct cdev *)device_create(ckgen_class, NULL, mt8193_ckgen_devno, NULL, MT8193_CKGEN_DEVNAME);
+
+ pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (IS_ERR(pinctrl)) {
+ ret = PTR_ERR(pinctrl);
+ pr_err("Cannot find pinctrl, ret=%d!\n", ret);
+ return ret;
+ }
+
+ pins_gpio = pinctrl_lookup_state(pinctrl, "bus_switch_gpio");
+ if (IS_ERR(pins_gpio)) {
+ ret = PTR_ERR(pins_gpio);
+ pr_err("Cannot find bus_switch_gpio, ret=%d!\n", ret);
+ return ret;
+ }
+
+ pins_dpi = pinctrl_lookup_state(pinctrl, "bus_switch_dpi");
+ if (IS_ERR(pins_dpi)) {
+ ret = PTR_ERR(pins_dpi);
+ pr_err("Cannot find bus_switch_dpi, ret=%d!\n", ret);
+ return ret;
+ }
+#endif
+ return 0;
+}
+
+/******************************************************************************
+ * mt8193_ckgen_remove
+ *
+ * DESCRIPTION:
+ * unregister the nand device file operations !
+ *
+ * PARAMETERS:
+ * struct platform_device *pdev : device structure
+ *
+ * RETURNS:
+ * 0 : Success
+ *
+ * NOTES:
+ * None
+ *
+ ******************************************************************************/
+
+static int mt8193_ckgen_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static void mt8193_ckgen_shutdown(struct platform_device *pdev)
+{
+ if (!multibridge_exit) {
+ multibridge_exit = 1;
+ mt8193_bus_clk_switch(false);
+ }
+}
+
+module_init(mt8193_ckgen_init);
+module_exit(mt8193_ckgen_exit);
+
+int mt8193_CKGEN_AgtOnClk(enum e_CLK_T eAgt)
+{
+ u32 u4Tmp;
+
+ pr_debug("mt8193_CKGEN_AgtOnClk() %d\n", eAgt);
+
+ switch (eAgt) {
+ case e_CLK_NFI:
+ u4Tmp = CKGEN_READ32(REG_RW_NFI_CKCFG);
+ CKGEN_WRITE32(REG_RW_NFI_CKCFG, u4Tmp & (~CLK_PDN_NFI));
+ break;
+ case e_CLK_HDMIPLL:
+ u4Tmp = CKGEN_READ32(REG_RW_HDMI_PLL_CKCFG);
+ CKGEN_WRITE32(REG_RW_HDMI_PLL_CKCFG, u4Tmp & (~CLK_PDN_HDMI_PLL));
+ break;
+ case e_CLK_HDMIDISP:
+ u4Tmp = CKGEN_READ32(REG_RW_HDMI_DISP_CKCFG);
+ CKGEN_WRITE32(REG_RW_HDMI_DISP_CKCFG, u4Tmp & (~CLK_PDN_HDMI_DISP));
+ break;
+ case e_CLK_LVDSDISP:
+ u4Tmp = CKGEN_READ32(REG_RW_LVDS_DISP_CKCFG);
+ CKGEN_WRITE32(REG_RW_LVDS_DISP_CKCFG, u4Tmp & (~CLK_PDN_LVDS_DISP));
+ break;
+ case e_CLK_LVDSCTS:
+ u4Tmp = CKGEN_READ32(REG_RW_LVDS_CTS_CKCFG);
+ CKGEN_WRITE32(REG_RW_LVDS_DISP_CKCFG, u4Tmp & (~CLK_PDN_LVDS_CTS));
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+int mt8193_CKGEN_AgtOffClk(enum e_CLK_T eAgt)
+{
+ u32 u4Tmp;
+
+ pr_debug("mt8193_CKGEN_AgtOffClk() %d\n", eAgt);
+
+ switch (eAgt) {
+ case e_CLK_NFI:
+ u4Tmp = CKGEN_READ32(REG_RW_NFI_CKCFG);
+ CKGEN_WRITE32(REG_RW_NFI_CKCFG, u4Tmp | CLK_PDN_NFI);
+ break;
+ case e_CLK_HDMIPLL:
+ u4Tmp = CKGEN_READ32(REG_RW_HDMI_PLL_CKCFG);
+ CKGEN_WRITE32(REG_RW_HDMI_PLL_CKCFG, u4Tmp | CLK_PDN_HDMI_PLL);
+ break;
+ case e_CLK_HDMIDISP:
+ u4Tmp = CKGEN_READ32(REG_RW_HDMI_DISP_CKCFG);
+ CKGEN_WRITE32(REG_RW_HDMI_DISP_CKCFG, u4Tmp | CLK_PDN_HDMI_DISP);
+ break;
+ case e_CLK_LVDSDISP:
+ u4Tmp = CKGEN_READ32(REG_RW_LVDS_DISP_CKCFG);
+ CKGEN_WRITE32(REG_RW_LVDS_DISP_CKCFG, u4Tmp | CLK_PDN_LVDS_DISP);
+ break;
+ case e_CLK_LVDSCTS:
+ u4Tmp = CKGEN_READ32(REG_RW_LVDS_CTS_CKCFG);
+ CKGEN_WRITE32(REG_RW_LVDS_DISP_CKCFG, u4Tmp | CLK_PDN_LVDS_CTS);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+int mt8193_CKGEN_AgtSelClk(enum e_CLK_T eAgt, u32 u4Sel)
+{
+ u32 u4Tmp;
+
+ pr_debug("mt8193_CKGEN_AgtSelClk() %d\n", eAgt);
+
+ switch (eAgt) {
+ case e_CLK_NFI:
+ u4Tmp = CKGEN_READ32(REG_RW_NFI_CKCFG);
+ CKGEN_WRITE32(REG_RW_NFI_CKCFG, u4Tmp | u4Sel);
+ break;
+ case e_CLK_HDMIPLL:
+ u4Tmp = CKGEN_READ32(REG_RW_HDMI_PLL_CKCFG);
+ CKGEN_WRITE32(REG_RW_HDMI_PLL_CKCFG, u4Tmp | u4Sel);
+ break;
+ case e_CLK_HDMIDISP:
+ u4Tmp = CKGEN_READ32(REG_RW_HDMI_DISP_CKCFG);
+ CKGEN_WRITE32(REG_RW_HDMI_DISP_CKCFG, u4Tmp | u4Sel);
+ break;
+ case e_CLK_LVDSDISP:
+ u4Tmp = CKGEN_READ32(REG_RW_LVDS_DISP_CKCFG);
+ CKGEN_WRITE32(REG_RW_LVDS_DISP_CKCFG, u4Tmp | u4Sel);
+ break;
+ case e_CLK_LVDSCTS:
+ u4Tmp = CKGEN_READ32(REG_RW_LVDS_CTS_CKCFG);
+ CKGEN_WRITE32(REG_RW_LVDS_DISP_CKCFG, u4Tmp | u4Sel);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+u32 mt8193_CKGEN_AgtGetClk(enum e_CLK_T eAgt)
+{
+ return 0;
+}
+
+int mt8193_ckgen_i2c_write(u16 addr, u32 data)
+{
+ u32 u4_ret = 0;
+
+ pr_debug("mt8193_ckgen_i2c_write() 0x%x; 0x%x\n", addr, data);
+ u4_ret = mt8193_i2c_write(addr, data);
+ if (u4_ret != 0)
+ pr_err("mt8193_i2c_read() fails!!!!!!\n");
+
+ return 0;
+}
+
+u32 mt8193_ckgen_i2c_read(u16 addr)
+{
+ u32 u4_val = 0;
+ u32 u4_ret = 0;
+
+ u4_ret = mt8193_i2c_read(addr, &u4_val);
+ if (u4_ret != 0)
+ pr_err("mt8193_i2c_read() fails!!!!!!\n");
+
+ pr_debug("mt8193_ckgen_i2c_read() 0x%x; value is 0x%x\n", addr, u4_val);
+ return u4_val;
+}
+
+/* freq meter measure clock */
+u32 mt8193_ckgen_measure_clk(u32 u4Func)
+{
+ u32 ui4_delay_cnt = 0x400;
+ u32 ui4_result = 0;
+
+ pr_debug("[CKGEN] mt8193_ckgen_measure_clk() %d\n", u4Func);
+
+ /* select source */
+ CKGEN_WRITE32(REG_RW_FMETER, (CKGEN_READ32(REG_RW_FMETER)&(~(0xFF<<3)))|(u4Func<<3));
+ /* start fmeter */
+ CKGEN_WRITE32(REG_RW_FMETER, (CKGEN_READ32(REG_RW_FMETER)|CKGEN_FMETER_RESET));
+ /* wait until fmeter done */
+ do {
+ ui4_delay_cnt--;
+ } while ((!(CKGEN_READ32(REG_RW_FMETER)&CKGEN_FMETER_DONE)) && ui4_delay_cnt);
+
+ ui4_result = CKGEN_READ32(REG_RW_FMETER)>>16;
+
+ pr_debug("[CKGEN] Measure Done CLK [0X%X] for func [%d] delay count [0x%X]\n",
+ ui4_result, u4Func, ui4_delay_cnt);
+
+ return ui4_result;
+}
+
+void mt8193_lvds_ana_pwr_control(bool power_on)
+{
+ u32 u4Tmp = 0;
+
+ if (power_on) {
+ u4Tmp = CKGEN_READ32(REG_RW_LVDS_ANACFG4);
+ u4Tmp &= (~LVDS_ANACFG4_VPlLL_PD);
+ CKGEN_WRITE32(REG_RW_LVDS_ANACFG4, u4Tmp);
+ } else {
+ u4Tmp = CKGEN_READ32(REG_RW_LVDS_ANACFG4);
+ u4Tmp |= (LVDS_ANACFG4_VPlLL_PD);
+ CKGEN_WRITE32(REG_RW_LVDS_ANACFG4, u4Tmp);
+ }
+}
+
+void mt8193_hdmi_ana_pwr_control(bool power_on)
+{
+ u32 u4Tmp = 0;
+
+ if (power_on) {
+ u4Tmp = CKGEN_READ32(REG_RW_HDMITX_ANACFG3);
+ u4Tmp |= (HDMITX_ANACFG3_BIT20);
+ u4Tmp |= (HDMITX_ANACFG3_BIT21);
+ CKGEN_WRITE32(REG_RW_HDMITX_ANACFG3, u4Tmp);
+ } else {
+ u4Tmp = CKGEN_READ32(REG_RW_HDMITX_ANACFG3);
+ u4Tmp &= (~HDMITX_ANACFG3_BIT20);
+ u4Tmp &= (~HDMITX_ANACFG3_BIT21);
+ CKGEN_WRITE32(REG_RW_HDMITX_ANACFG3, u4Tmp);
+ }
+}
+
+void mt8193_pllgp_ana_pwr_control(bool power_on)
+{
+ u32 u4Tmp = 0;
+
+ if (power_on) {
+ u4Tmp = CKGEN_READ32(REG_RW_PLLGP_ANACFG0);
+ u4Tmp |= (PLLGP_ANACFG0_PLL1_EN);
+ CKGEN_WRITE32(REG_RW_PLLGP_ANACFG0, u4Tmp);
+ } else {
+ u4Tmp = CKGEN_READ32(REG_RW_PLLGP_ANACFG0);
+ u4Tmp &= (~PLLGP_ANACFG0_PLL1_EN);
+ CKGEN_WRITE32(REG_RW_PLLGP_ANACFG0, u4Tmp);
+ }
+}
+
+void mt8193_nfi_ana_pwr_control(bool power_on)
+{
+ u32 u4Tmp = 0;
+
+ pr_debug("[CKGEN] mt8193_nfi_ana_pwr_control() %d\n", power_on);
+ if (power_on) {
+ u4Tmp = CKGEN_READ32(REG_RW_PLLGP_ANACFG2);
+ u4Tmp |= (PLLGP_ANACFG2_PLLGP_BIAS_EN);
+ CKGEN_WRITE32(REG_RW_PLLGP_ANACFG2, u4Tmp);
+
+ u4Tmp = CKGEN_READ32(REG_RW_PLLGP_ANACFG0);
+ u4Tmp |= (PLLGP_ANACFG0_PLL1_NFIPLL_EN);
+ CKGEN_WRITE32(REG_RW_PLLGP_ANACFG0, u4Tmp);
+ } else {
+ u4Tmp = CKGEN_READ32(REG_RW_PLLGP_ANACFG0);
+ u4Tmp &= (~PLLGP_ANACFG0_PLL1_NFIPLL_EN);
+ CKGEN_WRITE32(REG_RW_PLLGP_ANACFG0, u4Tmp);
+ msleep(20);
+ u4Tmp = CKGEN_READ32(REG_RW_PLLGP_ANACFG2);
+ u4Tmp &= (~PLLGP_ANACFG2_PLLGP_BIAS_EN);
+ CKGEN_WRITE32(REG_RW_PLLGP_ANACFG2, u4Tmp);
+ msleep(20);
+ }
+}
+
+void mt8193_lvds_sys_spm_control(bool power_on)
+{
+ u32 u4Tmp = 0;
+ u32 u4Tmp2 = 0;
+ u32 ui4_delay_cnt = 0x40000;
+
+ if (power_on) {
+ /* turn on power */
+ u4Tmp = CKGEN_READ32(REG_RW_LVDS_PWR_CTRL);
+ u4Tmp |= CKGEN_LVDS_PWR_PWR_ON;
+ CKGEN_WRITE32(REG_RW_LVDS_PWR_CTRL, u4Tmp);
+
+ /* disable reset */
+ u4Tmp2 = CKGEN_READ32(REG_RW_LVDS_PWR_RST_B);
+ u4Tmp2 |= CKGEN_LVDS_PWR_RST_EN;
+ CKGEN_WRITE32(REG_RW_LVDS_PWR_RST_B, u4Tmp2);
+
+ /* disable iso */
+ u4Tmp &= (~CKGEN_LVDS_PWR_ISO_EN);
+ CKGEN_WRITE32(REG_RW_LVDS_PWR_CTRL, u4Tmp);
+
+ /* enable clock */
+ u4Tmp &= (~CKGEN_LVDS_PWR_CLK_OFF);
+ CKGEN_WRITE32(REG_RW_LVDS_PWR_CTRL, u4Tmp);
+
+ /* wait until pwr act */
+ do {
+ ui4_delay_cnt--;
+ } while ((!(CKGEN_READ32(REG_RO_PWR_ACT)&CKGEN_LVDS_PWR_ON_ACT)) && ui4_delay_cnt);
+
+ if (ui4_delay_cnt == 0)
+ pr_err("[CKGEN] Did not get power act for LVDS!!!!\n");
+ } else {
+ /* disable clock */
+ u4Tmp = CKGEN_READ32(REG_RW_LVDS_PWR_CTRL);
+ u4Tmp |= CKGEN_LVDS_PWR_CLK_OFF;
+ CKGEN_WRITE32(REG_RW_LVDS_PWR_CTRL, u4Tmp);
+
+ /* enable iso */
+ u4Tmp |= CKGEN_LVDS_PWR_ISO_EN;
+ CKGEN_WRITE32(REG_RW_LVDS_PWR_CTRL, u4Tmp);
+
+ /* enable reset */
+ u4Tmp2 = CKGEN_READ32(REG_RW_LVDS_PWR_RST_B);
+ u4Tmp2 &= (~CKGEN_LVDS_PWR_RST_EN);
+ CKGEN_WRITE32(REG_RW_LVDS_PWR_RST_B, u4Tmp2);
+
+ /* turn off power */
+ u4Tmp &= (~CKGEN_LVDS_PWR_PWR_ON);
+ CKGEN_WRITE32(REG_RW_LVDS_PWR_CTRL, u4Tmp);
+ }
+}
+
+void mt8193_hdmi_sys_spm_control(bool power_on)
+{
+ u32 u4Tmp = 0;
+ u32 u4Tmp2 = 0;
+ u32 ui4_delay_cnt = 0x40000;
+
+ if (power_on) {
+ /* turn on power */
+ u4Tmp = CKGEN_READ32(REG_RW_HDMI_PWR_CTRL);
+ u4Tmp |= CKGEN_HDMI_PWR_PWR_ON;
+ CKGEN_WRITE32(REG_RW_HDMI_PWR_CTRL, u4Tmp);
+
+ /* disable reset */
+ u4Tmp2 = CKGEN_READ32(REG_RW_HDMI_PWR_RST_B);
+ u4Tmp2 |= CKGEN_HDMI_PWR_RST_EN;
+ CKGEN_WRITE32(REG_RW_HDMI_PWR_RST_B, u4Tmp2);
+
+ /* disable iso */
+ u4Tmp &= (~CKGEN_HDMI_PWR_ISO_EN);
+ CKGEN_WRITE32(REG_RW_HDMI_PWR_CTRL, u4Tmp);
+
+ /* enable clock */
+ u4Tmp &= (~CKGEN_HDMI_PWR_CLK_OFF);
+ CKGEN_WRITE32(REG_RW_HDMI_PWR_CTRL, u4Tmp);
+
+ /* wait until pwr act */
+ do {
+ ui4_delay_cnt--;
+ } while ((!(CKGEN_READ32(REG_RO_PWR_ACT)&CKGEN_HDMI_PWR_ON_ACT)) && ui4_delay_cnt);
+
+ if (ui4_delay_cnt == 0)
+ pr_err("[CKGEN] Did not get power act for HDMI!!!!\n");
+ } else {
+ /* disable clock */
+ u4Tmp = CKGEN_READ32(REG_RW_HDMI_PWR_CTRL);
+ u4Tmp |= CKGEN_HDMI_PWR_CLK_OFF;
+ CKGEN_WRITE32(REG_RW_HDMI_PWR_CTRL, u4Tmp);
+
+ /* enable iso */
+ u4Tmp |= CKGEN_HDMI_PWR_ISO_EN;
+ CKGEN_WRITE32(REG_RW_HDMI_PWR_CTRL, u4Tmp);
+
+ /* enable reset */
+ u4Tmp2 = CKGEN_READ32(REG_RW_HDMI_PWR_RST_B);
+ u4Tmp2 &= (~CKGEN_HDMI_PWR_RST_EN);
+ CKGEN_WRITE32(REG_RW_HDMI_PWR_RST_B, u4Tmp2);
+
+ /* turn off power */
+ u4Tmp &= (~CKGEN_HDMI_PWR_PWR_ON);
+ CKGEN_WRITE32(REG_RW_HDMI_PWR_CTRL, u4Tmp);
+ }
+}
+
+void mt8193_nfi_sys_spm_control(bool power_on)
+{
+ u32 u4Tmp = 0;
+ u32 u4Tmp2 = 0;
+ u32 ui4_delay_cnt = 0x40000;
+
+ if (power_on) {
+ /* turn on power */
+ u4Tmp = CKGEN_READ32(REG_RW_NFI_PWR_CTRL);
+ u4Tmp |= CKGEN_NFI_PWR_PWR_ON;
+ CKGEN_WRITE32(REG_RW_NFI_PWR_CTRL, u4Tmp);
+
+ /* disable reset */
+ u4Tmp2 = CKGEN_READ32(REG_RW_NFI_PWR_RST_B);
+ u4Tmp2 |= CKGEN_NFI_PWR_RST_EN;
+ CKGEN_WRITE32(REG_RW_NFI_PWR_RST_B, u4Tmp2);
+
+ /* disable iso */
+ u4Tmp &= (~CKGEN_NFI_PWR_ISO_EN);
+ CKGEN_WRITE32(REG_RW_NFI_PWR_CTRL, u4Tmp);
+
+ /* enable clock */
+ u4Tmp &= (~CKGEN_NFI_PWR_CLK_OFF);
+ CKGEN_WRITE32(REG_RW_NFI_PWR_CTRL, u4Tmp);
+
+ /* wait until pwr act */
+ do {
+ ui4_delay_cnt--;
+ } while ((!(CKGEN_READ32(REG_RO_PWR_ACT)&CKGEN_NFI_PWR_ON_ACT)) && ui4_delay_cnt);
+
+ if (ui4_delay_cnt == 0)
+ pr_err("[CKGEN] Did not get power act for NFI!!!!\n");
+ } else {
+ /* disable clock */
+ u4Tmp = CKGEN_READ32(REG_RW_NFI_PWR_CTRL);
+ u4Tmp |= CKGEN_NFI_PWR_CLK_OFF;
+ CKGEN_WRITE32(REG_RW_NFI_PWR_CTRL, u4Tmp);
+
+ /* enable iso */
+ u4Tmp |= CKGEN_NFI_PWR_ISO_EN;
+ CKGEN_WRITE32(REG_RW_NFI_PWR_CTRL, u4Tmp);
+
+ /* enable reset */
+ u4Tmp2 = CKGEN_READ32(REG_RW_NFI_PWR_RST_B);
+ u4Tmp2 &= (~CKGEN_NFI_PWR_RST_EN);
+ CKGEN_WRITE32(REG_RW_NFI_PWR_RST_B, u4Tmp2);
+
+ /* turn off power */
+ u4Tmp &= (~CKGEN_NFI_PWR_PWR_ON);
+ CKGEN_WRITE32(REG_RW_NFI_PWR_CTRL, u4Tmp);
+ }
+}
+
+void mt8193_bus_clk_switch(bool bus_26m_to_32k)
+{
+ u32 u4Tmp = 0;
+ struct device_node *dn;
+ int bus_switch_pin;
+ int ret;
+
+ dn = of_find_compatible_node(NULL, NULL, "mediatek,mt8193-ckgen");
+ bus_switch_pin = of_get_named_gpio(dn, "bus_switch_pin", 0);
+ ret = gpio_request(bus_switch_pin, "8193 bus switch pin");
+ if (ret) {
+ pr_err("request gpio fail, ret=%d\n", ret);
+ return;
+ }
+
+ if (bus_26m_to_32k) {
+ /* bus clock switch from 26M to 32K */
+ /* sequence: out -> dir -> select -> enable -> mode */
+#if 0
+ mt_set_gpio_out(GPIO_MT8193_BUS_SWITCH_PIN, GPIO_OUT_ONE);
+ mt_set_gpio_dir(GPIO_MT8193_BUS_SWITCH_PIN, GPIO_DIR_OUT);
+ mt_set_gpio_pull_select(GPIO_MT8193_BUS_SWITCH_PIN, GPIO_PULL_UP);
+ mt_set_gpio_pull_enable(GPIO_MT8193_BUS_SWITCH_PIN, GPIO_PULL_ENABLE);
+ mt_set_gpio_mode(GPIO_MT8193_BUS_SWITCH_PIN, MT8193_BUS_SWITCH_PIN_GPIO_MODE);
+#else
+ pinctrl_select_state(pinctrl, pins_gpio);
+#endif
+
+ u4Tmp = CKGEN_READ32(REG_RW_DCXO_ANACFG9);
+ u4Tmp &= (~(DCXO_ANACFG9_BUS_CK_SOURCE_SEL_MASK << DCXO_ANACFG9_BUS_CK_SOURCE_SEL_SHIFT));
+#if defined(USING_MT8193_DPI1) && USING_MT8193_DPI1
+ u4Tmp |= (6 << DCXO_ANACFG9_BUS_CK_SOURCE_SEL_SHIFT);
+#else
+ u4Tmp |= (3 << DCXO_ANACFG9_BUS_CK_SOURCE_SEL_SHIFT);
+#endif
+ /* using a GPIO as auto switch source */
+ u4Tmp &= (~DCX0_ANACFG9_BUS_CK_CTRL_SEL);
+ /* enable bus_ck auto switch function */
+ u4Tmp |= (DCX0_ANACFG9_BUS_CK_AUTO_SWITCH_EN);
+ pr_debug("[early_suspend] u4Tmp=0x%x\n", u4Tmp);
+ CKGEN_WRITE32(REG_RW_DCXO_ANACFG9, u4Tmp);
+#if 0
+ mt_set_gpio_out(GPIO_MT8193_BUS_SWITCH_PIN, GPIO_OUT_ZERO);
+#else
+ gpio_set_value(bus_switch_pin, 0);
+#endif
+ msleep(20);
+ /* verify: reading register must fail if switch clock success */
+ u4Tmp = CKGEN_READ32(REG_RW_DCXO_ANACFG9);
+ } else {
+ /* bus clock switch from 32K to 26M */
+#if 0
+ mt_set_gpio_out(GPIO_MT8193_BUS_SWITCH_PIN, GPIO_OUT_ONE);
+#else
+ gpio_set_value(bus_switch_pin, 1);
+#endif
+ msleep(20);
+ u4Tmp = CKGEN_READ32(REG_RW_DCXO_ANACFG9);
+ u4Tmp &= (~(DCXO_ANACFG9_BUS_CK_SOURCE_SEL_MASK << DCXO_ANACFG9_BUS_CK_SOURCE_SEL_SHIFT));
+ pr_debug("[late_resume] u4Tmp=0x%x\n", u4Tmp);
+ CKGEN_WRITE32(REG_RW_DCXO_ANACFG9, u4Tmp);
+#if 0
+ mt_set_gpio_mode(GPIO_MT8193_BUS_SWITCH_PIN, MT8193_BUS_SWITCH_PIN_DPI_MODE);
+#else
+ pinctrl_select_state(pinctrl, pins_dpi);
+#endif
+ }
+
+ gpio_free(bus_switch_pin);
+}
+
+#if 0
+void mt8193_bus_clk_switch_to_26m(void)
+{
+ u32 u4Tmp = 0;
+
+ pr_debug(" mt8193_bus_clk_switch_to_26m()\n");
+
+ /* bus clock switch from 32K to 26M */
+
+ mt_set_gpio_out(GPIO_MT8193_BUS_SWITCH_PIN, GPIO_OUT_ONE);
+
+ mdelay(20);
+
+ u4Tmp = CKGEN_READ32(REG_RW_DCXO_ANACFG9);
+ u4Tmp &= (~(DCXO_ANACFG9_BUS_CK_SOURCE_SEL_MASK << DCXO_ANACFG9_BUS_CK_SOURCE_SEL_SHIFT));
+ CKGEN_WRITE32(REG_RW_DCXO_ANACFG9, u4Tmp);
+
+ mt_set_gpio_mode(GPIO_MT8193_BUS_SWITCH_PIN, MT8193_BUS_SWITCH_PIN_DPI_MODE);
+}
+#endif
+
+#if MT8193_DISABLE_DCXO
+
+/* disable dcxo ldo1, 8193 core clock buffer */
+void mt8193_disable_dcxo_core(void)
+{
+ u32 u4Tmp = 0;
+
+ pr_debug("mt8193_disable_dcxo_core()\n");
+
+ /* set bt clock buffer manual mode */
+ u4Tmp = CKGEN_READ32(REG_RW_DCXO_ANACFG2);
+ u4Tmp &= (~DCXO_ANACFG2_PO_MAN);
+ CKGEN_WRITE32(REG_RW_DCXO_ANACFG2, u4Tmp);
+
+ /* disable dcxo ldo2 at manual mode */
+ u4Tmp &= (~DCXO_ANACFG2_LDO1_MAN_EN);
+ CKGEN_WRITE32(REG_RW_DCXO_ANACFG2, u4Tmp);
+
+ /* disable dcxo ldo2*/
+ u4Tmp &= (~DCXO_ANACFG2_LDO1_EN);
+ CKGEN_WRITE32(REG_RW_DCXO_ANACFG2, u4Tmp);
+}
+
+/* enable dcxo ldo1, 8193 core clock buffer */
+void mt8193_enable_dcxo_core(void)
+{
+ u32 u4Tmp = 0;
+
+ pr_debug("mt8193_enable_dcxo_core()\n");
+
+ /* disable dcxo ldo2*/
+ u4Tmp = CKGEN_READ32(REG_RW_DCXO_ANACFG2);
+ u4Tmp |= DCXO_ANACFG2_LDO1_EN;
+ CKGEN_WRITE32(REG_RW_DCXO_ANACFG2, u4Tmp);
+
+ /* disable dcxo ldo2 at manual mode */
+ u4Tmp |= DCXO_ANACFG2_LDO1_MAN_EN;
+ CKGEN_WRITE32(REG_RW_DCXO_ANACFG2, u4Tmp);
+
+ /* set bt clock buffer manual mode */
+
+ u4Tmp |= DCXO_ANACFG2_PO_MAN;
+ CKGEN_WRITE32(REG_RW_DCXO_ANACFG2, u4Tmp);
+}
+
+#endif
+
+#if 0
+void mt8193_en_bb_ctrl(bool pd)
+{
+ /* GPIO60 is EN_BB */
+ /* GPIO59 is CK_SEL */
+ if (pd) {
+ /* pull low */
+ mt_set_gpio_out(GPIO60, 0);
+ mt_set_gpio_out(GPIO59, 0);
+ } else {
+ /* pull high */
+ mt_set_gpio_out(GPIO59, 1);
+ mt_set_gpio_out(GPIO60, 1);
+ }
+}
+#endif
+
+/******************************************************************************
+ * mt8193_ckgen_suspend
+ *
+ * DESCRIPTION:
+ * Suspend the nand device!
+ *
+ * PARAMETERS:
+ * struct platform_device *pdev : device structure
+ *
+ * RETURNS:
+ * 0 : Success
+ *
+ * NOTES:
+ * None
+ *
+ ******************************************************************************/
+static int mt8193_ckgen_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ pr_debug("[CKGEN] mt8193_ckgen_suspend() enter\n");
+
+#if MT8193_MLC
+
+ /* If we use 8193 NFI, we should turn off pllgp in suspend because early suspend state may still use NFI.
+ Otherwise, we can turn off pllgp in early suspend. */
+
+ /* add 8193 suspend function here */
+
+ mt8193_pllgp_ana_pwr_control(false);
+ msleep(20);
+
+ /* bus clk switch to 32K */
+ mt8193_bus_clk_switch(true);
+ msleep(50);
+#endif
+ pr_debug("[CKGEN] mt8193_ckgen_suspend() exit\n");
+
+ return 0;
+}
+/******************************************************************************
+ * mt8193_ckgen_resume
+ *
+ * DESCRIPTION:
+ * Resume the nand device!
+ *
+ * PARAMETERS:
+ * struct platform_device *pdev : device structure
+ *
+ * RETURNS:
+ * 0 : Success
+ *
+ * NOTES:
+ * None
+ *
+ ******************************************************************************/
+static int mt8193_ckgen_resume(struct platform_device *pdev)
+{
+ pr_debug("[CKGEN] mt8193_ckgen_resume() enter\n");
+
+ /* If we use 8193 NFI, we should turn off pllgp in suspend because early suspend state may still use NFI.
+ Otherwise, we can turn off pllgp in early suspend. */
+
+#if MT8193_MLC
+ /* add 8193 resume function here */
+ /* bus clk switch to 26M */
+ mt8193_bus_clk_switch(false);
+ msleep(20);
+ /* turn on pllgp analog */
+ mt8193_pllgp_ana_pwr_control(true);
+ msleep(20);
+#endif
+ pr_debug("[CKGEN] mt8193_ckgen_resume() exit\n");
+
+ return 0;
+}
diff --git a/drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_ckgen_vfy.c b/drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_ckgen_vfy.c
new file mode 100644
index 000000000000..8c8969fc877d
--- /dev/null
+++ b/drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_ckgen_vfy.c
@@ -0,0 +1,501 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#if defined(CONFIG_MTK_MULTIBRIDGE_SUPPORT)
+
+#define MT8193_CKGEN_VFY 1
+
+#if MT8193_CKGEN_VFY
+
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/cdev.h>
+#include "mt8193.h"
+#include "mt8193_ckgen.h"
+
+
+int mt8193_ckgen_config_pad_level_shift(int i4GroupNum, int i4TurnLow)
+{
+ u32 u4Tmp;
+
+ pr_debug("[CKGEN] mt8193_ckgen_config_pad_level_shift() %d, %d\n", i4GroupNum, i4TurnLow);
+
+ if (i4TurnLow == 0) {
+ /* 3.3V->1.8V */
+ u4Tmp = CKGEN_READ32(REG_RW_LS_CTRL);
+ u4Tmp |= LS_CTRL_SHIFT_LOW_EN;
+ CKGEN_WRITE32(REG_RW_LS_CTRL, u4Tmp);
+ u4Tmp &= (~(1U<<i4GroupNum));
+ CKGEN_WRITE32(REG_RW_LS_CTRL, u4Tmp);
+ } else {
+ /* 1.8V -> 3.3V */
+ u4Tmp = CKGEN_READ32(REG_RW_LS_CTRL);
+ u4Tmp |= LS_CTRL_SHIFT_HIGH_EN;
+ CKGEN_WRITE32(REG_RW_LS_CTRL, u4Tmp);
+ u4Tmp |= (1U<<i4GroupNum);
+ CKGEN_WRITE32(REG_RW_LS_CTRL, u4Tmp);
+ }
+
+ pr_debug("[CKGEN] LS_CTRL: 0x%x\n", u4Tmp);
+
+ return 0;
+}
+
+u32 mt8193_ckgen_reg_rw_test(u16 addr)
+{
+ u32 u4Loop = 0;
+
+ pr_debug("[CKGEN] mt8193_ckgen_reg_rw_test() 0x%x\n", addr);
+
+ for (; u4Loop < 0xFFFF; u4Loop += 0x10) {
+ CKGEN_WRITE32(addr, u4Loop);
+ if (CKGEN_READ32(addr) != u4Loop) {
+ pr_err("[CKGEN] reg rw test fail at loop 0x%x\n", u4Loop);
+ return -1;
+ }
+ }
+
+ pr_debug("[CKGEN] mt8193_ckgen_reg_rw_test() success at 0x%x\n", addr);
+
+ return 0;
+}
+
+
+u32 mt8193_ckgen_bus_clk_switch_xtal_test(u16 addr)
+{
+ /* switch bus clock to 32k. pdwn dcxo. rw register */
+ u32 u4Tmp = 0;
+
+ /* swicth bus clock to 32k */
+ u4Tmp = CKGEN_READ32(REG_RW_BUS_CKCFG);
+ CKGEN_WRITE32(REG_RW_BUS_CKCFG, (u4Tmp & (~(0xF))) | CLK_BUS_SEL_32K);
+ return 0;
+}
+
+u32 mt8193_io_agent_test(void)
+{
+ u32 u4Tmp = 0;
+
+ pr_debug("[CKGEN] IO AGENT TEST ------------------------------------------\n");
+
+ IO_WRITE32(0x1000, 0x500, 0x55555555);
+ u4Tmp = IO_READ32(0x1000, 0x500);
+ if (u4Tmp == 0x55555555)
+ pr_debug("[CKGEN] TEST PASS at 0x1500\n");
+ else
+ pr_err("[CKGEN] TEST FAIL at 0x1500. [0x%x] !!!!!!!!!!\n", u4Tmp);
+
+ IO_WRITE32(0x0, 0x18, 0x55555555);
+ u4Tmp = IO_READ32(0x0, 0x18);
+ if (u4Tmp == 0x55555555)
+ pr_debug("[CKGEN] TEST PASS at 0x18\n");
+ else
+ pr_err("[CKGEN] TEST FAIL at 0x18. [0x%x] !!!!!!!!!!\n", u4Tmp);
+
+ IO_WRITE32(0x0, 0x0408, 0x55555555);
+ u4Tmp = IO_READ32(0x0, 0x408);
+ if (u4Tmp == 0x55555555)
+ pr_debug("[CKGEN] TEST PASS at 0x408\n");
+ else
+ pr_err("[CKGEN] TEST FAIL at 0x408. [0x%x] !!!!!!!!!!\n", u4Tmp);
+
+ IO_WRITE32(0x0, 0x0608, 0x55555555);
+ u4Tmp = IO_READ32(0x0, 0x608);
+ if (u4Tmp == 0x55555555)
+ pr_debug("[CKGEN] TEST PASS at 0x608\n");
+ else
+ pr_err("[CKGEN] TEST FAIL at 0x608. [0x%x] !!!!!!!!!!\n", u4Tmp);
+
+ IO_WRITE32(0x0, 0x0a10, 0x55555555);
+ u4Tmp = IO_READ32(0x0, 0xa10);
+ if (u4Tmp == 0x00055555)
+ pr_debug("[CKGEN] TEST PASS at 0xa10\n");
+ else
+ pr_err("[CKGEN] TEST FAIL at 0xa10. [0x%x] !!!!!!!!!!\n", u4Tmp);
+
+ IO_WRITE32(0x1000, 0x200, 0xaaaaffff);
+ u4Tmp = IO_READ32(0x1000, 0x200);
+ if (u4Tmp == 0xaaaaffff)
+ pr_debug("[CKGEN] TEST PASS at 0x1200\n");
+ else
+ pr_err("[CKGEN] TEST FAIL at 0x1200. [0x%x] !!!!!!!!!!\n", u4Tmp);
+
+ IO_WRITE32(0x1000, 0x608, 0x05550555);
+ u4Tmp = IO_READ32(0x1000, 0x608);
+ if (u4Tmp == 0x05550555)
+ pr_debug("[CKGEN] TEST PASS at 0x1608\n");
+ else
+ pr_err("[CKGEN] TEST FAIL at 0x1608. [0x%x] !!!!!!!!!!\n", u4Tmp);
+
+ IO_WRITE32(0x1000, 0x708, 0x55555555);
+ u4Tmp = IO_READ32(0x1000, 0x708);
+ if (u4Tmp == 0x55555555)
+ pr_debug("[CKGEN] TEST PASS at 0x1708\n");
+ else
+ pr_err("[CKGEN] TEST FAIL at 0x1708. [0x%x] !!!!!!!!!!\n", u4Tmp);
+
+ IO_WRITE32(0x1000, 0xd00, 0x55555555);
+ u4Tmp = IO_READ32(0x1000, 0xd00);
+ if (u4Tmp == 0x55555555)
+ pr_debug("[CKGEN] TEST PASS at 0x1d00\n");
+ else
+ pr_err("[CKGEN] TEST FAIL at 0x1d00. [0x%x] !!!!!!!!!!\n", u4Tmp);
+
+ IO_WRITE32(0x1000, 0xd00, 0xaaaaaaaa);
+ u4Tmp = IO_READ32(0x1000, 0xd00);
+ if (u4Tmp == 0xaaaaaaaa)
+ pr_debug("[CKGEN] TEST PASS at 0x1d00\n");
+ else
+ pr_err("[CKGEN] TEST FAIL at 0x1d00. [0x%x] !!!!!!!!!!\n", u4Tmp);
+
+ pr_debug("[CKGEN] IO AGENT TEST FINISH ------------------------------------------\n");
+
+ return 0;
+}
+
+void mt8193_hdmi_on_test(void)
+{
+ int i = 0;
+ u32 u4Crc = 0;
+
+ mt8193_i2c_write(0x1254, 0x00000323);
+ msleep(100);
+ mt8193_i2c_write(0x101c, 0x00000004);
+ msleep(100);
+ mt8193_i2c_write(0x1328, 0x00009999);
+ msleep(100);
+ mt8193_i2c_write(0x1334, 0x0020008f);
+ msleep(100);
+ mt8193_i2c_write(0x1338, 0xd4a88f00);
+ msleep(100);
+ mt8193_i2c_write(0x1344, 0x00008012);
+ msleep(100);
+ mt8193_i2c_write(0x1348, 0x11ff0000);
+ msleep(100);
+ mt8193_i2c_write(0x1334, 0x0030008f);
+ msleep(100);
+ mt8193_i2c_write(0x02d4, 0x02);
+ msleep(100);
+ mt8193_i2c_write(0x02d8, 0x80);
+ msleep(100);
+ mt8193_i2c_write(0x0448, 0x00000);
+ msleep(100);
+ mt8193_i2c_write(0x0450, 0x2);
+ msleep(100);
+ mt8193_i2c_write(0x0608, 0x80000005);
+ msleep(100);
+ mt8193_i2c_write(0x065c, 0x0000000f);
+ msleep(100);
+ mt8193_i2c_write(0x0604, 0x00000040);
+ msleep(100);
+ mt8193_i2c_write(0x061c, 0x00104000);
+ msleep(100);
+ mt8193_i2c_write(0x0624, 0x02ee07bc);
+ msleep(100);
+ mt8193_i2c_write(0x0628, 0x00030005);
+ msleep(100);
+ mt8193_i2c_write(0x0630, 0x0080057f);
+ msleep(100);
+ mt8193_i2c_write(0x0634, 0x001002df);
+ msleep(100);
+ mt8193_i2c_write(0x0638, 0x001002df);
+ msleep(100);
+ mt8193_i2c_write(0x0620, 0x000207ba);
+ msleep(100);
+ mt8193_i2c_write(0x0600, 0x00000001);
+ msleep(100);
+ mt8193_i2c_write(0x060c, 0x00000002);
+ msleep(100);
+ mt8193_i2c_write(0x0700, 0x02ee07bc);
+ msleep(100);
+ mt8193_i2c_write(0x0704, 0x00030005);
+ msleep(100);
+ mt8193_i2c_write(0x0708, 0x01000080);
+ msleep(100);
+ mt8193_i2c_write(0x070c, 0x02d00500);
+ msleep(100);
+ mt8193_i2c_write(0x0710, 0x00000203);
+ msleep(100);
+ mt8193_i2c_write(0x0714, 0x00ff8844);
+ msleep(100);
+ mt8193_i2c_write(0x0718, 0x000000ff);
+ msleep(100);
+
+ for (; i < 100; i++) {
+ u32 u4Crc_2 = 0;
+
+ mt8193_i2c_write(0x071c, 2);
+ msleep(50);
+ mt8193_i2c_write(0x071c, 1);
+ msleep(50);
+ mt8193_i2c_read(0x0720, &u4Crc_2);
+ msleep(50);
+
+ if (i > 1 && u4Crc_2 != u4Crc) {
+ pr_err("[HDMI] CHECK CRC ERROR! 0x%x, 0x%x, %d\n", u4Crc, u4Crc_2, i);
+ break;
+ } else {
+ pr_debug("[HDMI] CHECK CRC OK %d\n", i);
+ }
+
+ u4Crc = u4Crc_2;
+ }
+}
+
+void mt8193_spm_control_test(int u4Func)
+{
+ pr_debug("[CKGEN] mt8193_spm_control_test()enters. %d\n", u4Func);
+
+ /* mt8193_io_agent_test(); */
+
+ if (u4Func == 0) {
+ /* loop 1 */
+ mt8193_lvds_sys_spm_control(false);
+ msleep(1000);
+ mt8193_hdmi_sys_spm_control(false);
+ msleep(1000);
+ mt8193_nfi_sys_spm_control(false);
+ msleep(1000);
+
+ mt8193_lvds_sys_spm_control(true);
+ msleep(1000);
+ mt8193_hdmi_sys_spm_control(true);
+ msleep(1000);
+ mt8193_nfi_sys_spm_control(true);
+ msleep(1000);
+
+ mt8193_io_agent_test();
+
+ /* loop 2 */
+ mt8193_hdmi_sys_spm_control(false);
+ msleep(1000);
+ mt8193_lvds_sys_spm_control(false);
+ msleep(1000);
+ mt8193_nfi_sys_spm_control(false);
+ msleep(1000);
+
+ mt8193_lvds_sys_spm_control(true);
+ msleep(1000);
+ mt8193_hdmi_sys_spm_control(true);
+ msleep(1000);
+ mt8193_nfi_sys_spm_control(true);
+ msleep(1000);
+
+ mt8193_io_agent_test();
+
+ /* loop 3 */
+ mt8193_nfi_sys_spm_control(false);
+ msleep(1000);
+ mt8193_lvds_sys_spm_control(false);
+ msleep(1000);
+ mt8193_hdmi_sys_spm_control(false);
+ msleep(1000);
+
+ mt8193_lvds_sys_spm_control(true);
+ msleep(1000);
+ mt8193_hdmi_sys_spm_control(true);
+ msleep(1000);
+ mt8193_nfi_sys_spm_control(true);
+ msleep(1000);
+
+ mt8193_io_agent_test();
+
+ /* loop 4 */
+ mt8193_lvds_sys_spm_control(false);
+ msleep(1000);
+ mt8193_nfi_sys_spm_control(false);
+ msleep(1000);
+ mt8193_hdmi_sys_spm_control(false);
+ msleep(1000);
+
+ mt8193_lvds_sys_spm_control(true);
+ msleep(1000);
+ mt8193_hdmi_sys_spm_control(true);
+ msleep(1000);
+ mt8193_nfi_sys_spm_control(true);
+ msleep(1000);
+
+ mt8193_io_agent_test();
+
+ /* loop 5 */
+
+ mt8193_hdmi_sys_spm_control(false);
+ msleep(1000);
+ mt8193_lvds_sys_spm_control(false);
+ msleep(1000);
+ mt8193_nfi_sys_spm_control(false);
+ msleep(1000);
+
+ mt8193_lvds_sys_spm_control(true);
+ msleep(1000);
+ mt8193_hdmi_sys_spm_control(true);
+ msleep(1000);
+ mt8193_nfi_sys_spm_control(true);
+ msleep(1000);
+
+ mt8193_io_agent_test();
+ } else if (u4Func == 1) {
+ /*
+ step 1: turn off digital
+ step 2: turn off analog
+ step3: BUS CLK SWITCH TO 32K
+ step4: PULL LOW EN_BB & CK_SEL
+ Step5: PULL UP EN_BB & CK_SEL
+ step6: BUS CLK SWITCH to 26M
+ step7: turn on analog
+ step8: turn on digital
+ step9: test function
+ */
+ /* lvds spm ctrl test */
+ mt8193_lvds_sys_spm_control(false);
+ msleep(100);
+ /*mt8193_hdmi_sys_spm_control(false);*/
+ msleep(100);
+ /*mt8193_nfi_sys_spm_control(false);*/
+ msleep(100);
+
+ mt8193_lvds_ana_pwr_control(false);
+ msleep(100);
+ /*mt8193_hdmi_ana_pwr_control(false);*/
+ msleep(100);
+ mt8193_pllgp_ana_pwr_control(false);
+ msleep(100);
+ /*mt8193_nfi_ana_pwr_control(false);*/
+ msleep(1000);
+
+ /* bus clk switch to 32K*/
+ mt8193_bus_clk_switch(true);
+
+ msleep(20);
+ /* pull low en_bb */
+ /* mt8193_en_bb_ctrl(true); */
+
+ msleep(100);
+
+ /* pull up en_bb */
+ /* mt8193_en_bb_ctrl(false); */
+
+ /* msleep(20); */
+
+ /* bus clk switch to 26M */
+ mt8193_bus_clk_switch(false);
+
+ /*mt8193_nfi_ana_pwr_control(true);*/
+ msleep(100);
+ mt8193_pllgp_ana_pwr_control(true);
+ msleep(100);
+ /*mt8193_hdmi_ana_pwr_control(true);*/
+ msleep(100);
+ mt8193_lvds_ana_pwr_control(true);
+ msleep(100);
+ mt8193_lvds_sys_spm_control(true);
+ msleep(100);
+ /*mt8193_hdmi_sys_spm_control(true);*/
+ msleep(100);
+ /*mt8193_nfi_sys_spm_control(true);*/
+ msleep(100);
+
+ /* lcm_mt8193_lvds_on_test();*/
+ } else if (u4Func == 2) {
+ /*int i = 0;*/
+
+ /*for (; i<=1000; i++) { */
+ /*pr_debug("[CKGEN] LOOP %d START-------------------------------------\n", i);*/
+ /* hdmi spm ctrl test */
+ msleep(1000);
+ mt8193_lvds_ana_pwr_control(false);
+ msleep(20);
+ mt8193_hdmi_ana_pwr_control(false);
+ msleep(20);
+ mt8193_pllgp_ana_pwr_control(false);
+ msleep(20);
+ mt8193_nfi_ana_pwr_control(false);
+ msleep(20);
+ mt8193_lvds_sys_spm_control(false);
+ msleep(20);
+ mt8193_hdmi_sys_spm_control(false);
+ msleep(20);
+ mt8193_nfi_sys_spm_control(false);
+ msleep(20);
+
+ /* bus clk switch to 32K */
+ mt8193_bus_clk_switch(true);
+
+ msleep(1000);
+ /* pull low en_bb */
+ /*mt8193_en_bb_ctrl(true);*/
+
+ /*msleep(100);*/
+
+ /* pull up en_bb*/
+ /*mt8193_en_bb_ctrl(false);*/
+
+ /*msleep(1);*/
+
+ /* bus clk switch to 26M */
+ mt8193_bus_clk_switch(false);
+ msleep(20);
+ mt8193_lvds_sys_spm_control(true);
+ msleep(20);
+ mt8193_hdmi_sys_spm_control(true);
+ msleep(20);
+ mt8193_nfi_sys_spm_control(true);
+ msleep(20);
+ mt8193_nfi_ana_pwr_control(true);
+ msleep(20);
+ mt8193_pllgp_ana_pwr_control(true);
+ msleep(20);
+ mt8193_hdmi_ana_pwr_control(true);
+ msleep(20);
+ mt8193_lvds_ana_pwr_control(true);
+ msleep(1000);
+
+ /*pr_debug("[CKGEN] LOOP %d END-------------------------------------\n", i); */
+ /*}*/
+
+ /*mt8193_hdmi_on_test();*/
+ } else if (u4Func == 3) {
+ /* nfi spm ctrl test */
+ mt8193_nfi_sys_spm_control(false);
+ msleep(1000);
+ mt8193_nfi_sys_spm_control(true);
+ msleep(1000);
+
+ mt8193_io_agent_test();
+ } else if (u4Func == 4) {
+ /* bus clk switch to 32K */
+ mt8193_bus_clk_switch(true);
+ msleep(20);
+ /* pull low en_bb */
+ /* mt8193_en_bb_ctrl(true); */
+ } else if (u4Func == 5) {
+ /* pull up en_bb */
+ /* mt8193_en_bb_ctrl(false); */
+ /* bus clk switch to 32K */
+ mt8193_bus_clk_switch(false);
+ }
+
+ pr_debug("[CKGEN] mt8193_spm_control() exit\n");
+}
+
+#endif
+#endif
diff --git a/drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_gpio.c b/drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_gpio.c
new file mode 100644
index 000000000000..b1d1c7c46d4d
--- /dev/null
+++ b/drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_gpio.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#define pr_fmt(fmt) "mt8193-gpio: " fmt
+
+#include <generated/autoconf.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/kthread.h>
+#include <linux/vmalloc.h>
+
+#include <linux/uaccess.h>
+#include <linux/atomic.h>
+#include <asm/cacheflush.h>
+#include <linux/io.h>
+
+#include <mach/irqs.h>
+
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/mm.h>
+#include <linux/cdev.h>
+#include <asm/tlbflush.h>
+#include <asm/page.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+
+#include <generated/autoconf.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/kthread.h>
+
+#include <linux/uaccess.h>
+#include <linux/atomic.h>
+#include <asm/cacheflush.h>
+#include <linux/io.h>
+
+#include <mach/irqs.h>
+#include <linux/vmalloc.h>
+
+#include <linux/uaccess.h>
+
+#include "mt8193_pinmux.h"
+#include "mt8193_gpio.h"
+#include "mt8193.h"
+
+
+/* config gpio input/output low/high */
+int GPIO_Config(u32 u4GpioNum, u8 u1Mode, u8 u1Value)
+{
+ int ret = 0;
+ u32 u4PadNum = 0;
+ u32 u4Tmp = 0;
+
+ if (u4GpioNum > GPIO_PIN_MAX) {
+ pr_err("[PINMUX] Invalid GPIO NUM %d\n", u4GpioNum);
+ return PINMUX_RET_INVALID_ARG;
+ }
+
+ u4PadNum = _au4GpioTbl[u4GpioNum];
+
+ pr_debug("[PINMUX] GPIO_Config() %d, %d, %d, %d\n", u4GpioNum, u4PadNum, u1Mode, u1Value);
+
+ if (u4PadNum >= PIN_NFD6 && u4PadNum <= PIN_NFD0) {
+ /* NFI ND GROUP. function 1 is gpio*/
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION1);
+ } else if (u4PadNum >= PIN_G0 && u4PadNum <= PIN_VSYNC) {
+ /* GRB OUT GROUP. function 0 is gpio */
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION0);
+ } else if (u4PadNum >= PIN_CEC && u4PadNum <= PIN_HTPLG) {
+ /* HDMI GROUP. function 2 is gpio */
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION2);
+ } else if (u4PadNum >= PIN_I2S_DATA && u4PadNum <= PIN_I2S_BCK) {
+ /* audio GROUP. function 3 is gpio */
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION3);
+ } else if (u4PadNum == PIN_DPI1CK) {
+ /* RGB_IN2 group. function 2 is gpio*/
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION2);
+ } else if (u4PadNum >= PIN_DPI1D7 && u4PadNum <= PIN_DPI1D0) {
+ /* RGB_IN1 GROUP. function 3 is gpio */
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION3);
+ } else if (u4PadNum >= PIN_DPI0CK && u4PadNum <= PIN_DPI0D3) {
+ /* RGB_IN1 GROUP. function 2 is gpio */
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION2);
+ } else if (u4PadNum >= PIN_DPI0D2 && u4PadNum <= PIN_DPI0D0) {
+ /* RGB_IN1 GROUP. function 1 is gpio */
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION1);
+ } else if (u4PadNum >= PIN_SDA && u4PadNum <= PIN_SCL) {
+ /* I2C_SLAVE GROUP. function 1 is gpio */
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION1);
+ } else if (u4PadNum >= PIN_NRNB && u4PadNum <= PIN_NLD7) {
+ /* NFI_6583 GROUP. function 2 is gpio */
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION2);
+ } else if (u4PadNum >= PIN_NLD6 && u4PadNum <= PIN_NLD3) {
+ /* NFI_6583 GROUP. function 3 is gpio */
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION3);
+ } else if (u4PadNum >= PIN_NLD2 && u4PadNum <= PIN_NLD0) {
+ /* NFI_6583 GROUP. function 2 is gpio */
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION2);
+ } else if (u4PadNum == PIN_INT) {
+ /* INTERRUPT group. function 3 is gpio*/
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION3);
+ } else if (u4PadNum >= PIN_NLD2 && u4PadNum <= PIN_NLD0) {
+ /* NFI_6583 GROUP. function 2 is gpio */
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION2);
+ } else if (u4PadNum == PIN_NFRBN) {
+ /* NFI_ND group. function 1 is gpio*/
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION1);
+ } else if (u4PadNum >= PIN_NFCLE && u4PadNum <= PIN_NFALE) {
+ /* NFI ND GROUP. function 3 is gpio*/
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION3);
+ } else if (u4PadNum >= PIN_NFWEN && u4PadNum <= PIN_NFD7) {
+ /* NFI ND GROUP. function 2 is gpio*/
+ ret = mt8193_pinset(u4PadNum, PINMUX_FUNCTION2);
+ } else {
+ pr_err("[PINMUX] GPIO CFG ERROR !\n");
+ return PINMUX_RET_INVALID_ARG;
+ }
+
+ if (u1Mode == MT8193_GPIO_OUTPUT) {
+ /* output*/
+ if (u4GpioNum >= 32 && u4GpioNum <= 63) {
+ u4Tmp = CKGEN_READ32(REG_RW_GPIO_EN_1);
+ u4Tmp |= (1 << (u4GpioNum-32));
+ CKGEN_WRITE32(REG_RW_GPIO_EN_1, u4Tmp);
+
+ u4Tmp = CKGEN_READ32(REG_RW_GPIO_OUT_1);
+
+ if (u1Value == MT8193_GPIO_HIGH)
+ u4Tmp |= (1 << (u4GpioNum-32));
+ else
+ u4Tmp &= (~(1 << (u4GpioNum-32)));
+
+ CKGEN_WRITE32(REG_RW_GPIO_OUT_1, u4Tmp);
+ } else if (u4GpioNum >= 0 && u4GpioNum <= 31) {
+ /* work around method for gpio0~gpio31 */
+ u32 u4PdShift = 0;
+ u32 u4PuShift = 0;
+
+ u4PdShift = _au4PinmuxPadPuPdTbl[u4PadNum][0];
+ u4PuShift = _au4PinmuxPadPuPdTbl[u4PadNum][1];
+
+ u4Tmp = CKGEN_READ32(REG_RW_GPIO_EN_0);
+
+ if (u1Value == MT8193_GPIO_HIGH) {
+ /* for output high, set en as 0. set pad pd as 0, set pad pu as 1 */
+ u4Tmp &= (~(1 << u4GpioNum));
+ CKGEN_WRITE32(REG_RW_GPIO_EN_0, u4Tmp);
+
+ if (u4PdShift <= 31) {
+ u4Tmp = CKGEN_READ32(REG_RW_PAD_PD0);
+ u4Tmp &= (~(1 << u4PdShift));
+ CKGEN_WRITE32(REG_RW_PAD_PD0, u4Tmp);
+
+ u4Tmp = CKGEN_READ32(REG_RW_PAD_PU0);
+ u4Tmp |= (1 << u4PdShift);
+ CKGEN_WRITE32(REG_RW_PAD_PU0, u4Tmp);
+ } else if (u4PdShift >= 32 && u4PdShift <= 63) {
+ u4Tmp = CKGEN_READ32(REG_RW_PAD_PD1);
+ u4Tmp &= (~(1 << (u4PdShift - 31)));
+ CKGEN_WRITE32(REG_RW_PAD_PD1, u4Tmp);
+
+ u4Tmp = CKGEN_READ32(REG_RW_PAD_PU1);
+ u4Tmp |= (1 << (u4PdShift - 31));
+ CKGEN_WRITE32(REG_RW_PAD_PU1, u4Tmp);
+ }
+ } else {
+ /* for output low, just set en as 1 */
+ u4Tmp |= (1 << u4GpioNum);
+ CKGEN_WRITE32(REG_RW_GPIO_EN_0, u4Tmp);
+ }
+
+ /* CKGEN_WRITE32(REG_RW_GPIO_OUT_0, u4Tmp); */
+ }
+ } else {
+ /* input*/
+ if (u4GpioNum >= 32 && u4GpioNum <= 63) {
+ u4Tmp = CKGEN_READ32(REG_RW_GPIO_EN_1);
+ u4Tmp &= (~(1 << (u4GpioNum-32)));
+ CKGEN_WRITE32(REG_RW_GPIO_EN_1, u4Tmp);
+ } else if (u4GpioNum >= 0 && u4GpioNum <= 31) {
+ u4Tmp = CKGEN_READ32(REG_RW_GPIO_EN_0);
+ u4Tmp &= (~(1 << u4GpioNum));
+ CKGEN_WRITE32(REG_RW_GPIO_EN_0, u4Tmp);
+ }
+ }
+
+ return PINMUX_RET_OK;
+}
+
+/* return MT8193_GPIO_HIGH or MT8193_GPIO_LOW */
+u8 GPIO_Input(u32 u4GpioNum)
+{
+ u32 u4Tmp = 0;
+ u8 u1Val = MT8193_GPIO_LOW;
+
+ if (u4GpioNum >= 32 && u4GpioNum <= 63) {
+ u4Tmp = CKGEN_READ32(REG_RW_GPIO_IN_1);
+ u1Val = (u4Tmp & (1 << (u4GpioNum-32))) ? MT8193_GPIO_HIGH : MT8193_GPIO_LOW;
+ } else if (u4GpioNum >= 0 && u4GpioNum <= 31) {
+ u4Tmp = CKGEN_READ32(REG_RW_GPIO_IN_0);
+ u1Val = (u4Tmp & (1 << u4GpioNum)) ? MT8193_GPIO_HIGH : MT8193_GPIO_LOW;
+ }
+
+ return u1Val;
+}
+
+int GPIO_Output(u32 u4GpioNum, u32 u4High)
+{
+ int ret = 0;
+
+ ret = GPIO_Config(u4GpioNum, MT8193_GPIO_OUTPUT, u4High);
+
+ return ret;
+}
diff --git a/drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_iic.c b/drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_iic.c
new file mode 100644
index 000000000000..09c208200402
--- /dev/null
+++ b/drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_iic.c
@@ -0,0 +1,479 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#define pr_fmt(fmt) "mt8193-iic: " fmt
+#define DEBUG 1
+
+#include <generated/autoconf.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/kthread.h>
+#include <linux/vmalloc.h>
+
+#include <linux/uaccess.h>
+#include <linux/atomic.h>
+#include <asm/cacheflush.h>
+#include <linux/io.h>
+
+#include <mach/irqs.h>
+
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/mm.h>
+#include <linux/cdev.h>
+#include <asm/tlbflush.h>
+#include <asm/page.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+
+#include <generated/autoconf.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/kthread.h>
+
+#include <linux/uaccess.h>
+#include <linux/atomic.h>
+#include <asm/cacheflush.h>
+#include <linux/io.h>
+
+#include <mach/irqs.h>
+#include <linux/vmalloc.h>
+
+#include <linux/uaccess.h>
+
+#include "mt8193_iic.h"
+#include "mt8193.h"
+/*#define HDMI_OPEN_PACAKAGE_SUPPORT*/
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <mt-plat/mt_gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pinctrl/consumer.h>
+#endif
+/*----------------------------------------------------------------------------*/
+/* mt8193 device information */
+/*----------------------------------------------------------------------------*/
+#define MAX_TRANSACTION_LENGTH 8
+#define MT8193_DEVICE_NAME "mtk-multibridge"
+#define MT8193_I2C_SLAVE_ADDR 0x3A
+#define MT8193_I2C_DEVICE_ADDR_LEN 2
+/*----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------*/
+static int mt8193_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id);
+static int mt8193_i2c_remove(struct i2c_client *client);
+static struct i2c_client *mt8193_i2c_client;
+static const struct i2c_device_id mt8193_i2c_id[] = {{MT8193_DEVICE_NAME, 0}, {} };
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+struct regulator *vldo28_pmu;
+struct regulator *vrf12_pmu;
+struct regulator *vibr_pmu;
+struct regulator *vmipi_pmu;
+struct device *mt8193_dev_context;
+static const struct of_device_id mt8193_i2c_mhl_id[] = {
+ {.compatible = "mediatek,ext_disp"},
+ {},
+ };
+char *rst_pin_name[2] = {"rst_default", "rst_high"};
+
+struct i2c_driver mt8193_i2c_driver = {
+ .probe = mt8193_i2c_probe,
+ .remove = mt8193_i2c_remove,
+ .driver = { .name = MT8193_DEVICE_NAME,
+ .of_match_table = mt8193_i2c_mhl_id,
+ },
+ .id_table = mt8193_i2c_id,
+};
+#else
+static struct i2c_board_info i2c_mt8193 __initdata = {I2C_BOARD_INFO(MT8193_DEVICE_NAME, (MT8193_I2C_SLAVE_ADDR>>1))};
+/*----------------------------------------------------------------------------*/
+struct i2c_driver mt8193_i2c_driver = {
+ .probe = mt8193_i2c_probe,
+ .remove = mt8193_i2c_remove,
+ .driver = { .name = MT8193_DEVICE_NAME, },
+ .id_table = mt8193_i2c_id,
+};
+#endif
+
+struct mt8193_i2c_data {
+ struct i2c_client *client;
+ uint16_t addr;
+ int use_reset; /*use RESET flag*/
+ int use_irq; /*use EINT flag*/
+ int retry;
+};
+
+static struct mt8193_i2c_data *obj_i2c_data;
+
+/*----------------------------------------------------------------------------*/
+int mt8193_i2c_read(u16 addr, u32 *data)
+{
+#if 0
+ u8 rxBuf[8] = {0};
+ int ret = 0;
+ struct i2c_client *client = mt8193_i2c_client;
+ u8 lens;
+
+ if (((addr >> 8) & 0xFF) >= 0x80) {
+ /* 8 bit : fast mode */
+ rxBuf[0] = (addr >> 8) & 0xFF;
+ lens = 1;
+ } else {
+ /* 16 bit : noraml mode */
+ rxBuf[0] = (addr >> 8) & 0xFF;
+ rxBuf[1] = addr & 0xFF;
+ lens = 2;
+ }
+
+ /*client->addr = (client->addr & I2C_MASK_FLAG);
+ client->ext_flag = I2C_WR_FLAG;*/
+ client->addr = client->addr;
+
+ ret = i2c_master_send(client, (const char *)&rxBuf, (4 << 8) | lens);
+ if (ret < 0) {
+ pr_err("%s: read error\n", __func__);
+ return -EFAULT;
+ }
+#else
+ struct i2c_client *client = mt8193_i2c_client;
+ struct i2c_msg msg[2];
+ u8 rxBuf[8] = {0};
+ u8 lens = 0;
+
+ if (((addr >> 8) & 0xFF) >= 0x80) {
+ /* 8 bit : fast mode */
+ rxBuf[0] = (addr >> 8) & 0xFF;
+ lens = 1;
+ } else {
+ /* 16 bit : noraml mode */
+ rxBuf[0] = (addr >> 8) & 0xFF;
+ rxBuf[1] = addr & 0xFF;
+ lens = 2;
+ }
+
+ msg[0].flags = 0;
+ msg[0].addr = client->addr;
+ msg[0].buf = rxBuf;
+ msg[0].len = lens;
+
+ msg[1].flags = I2C_M_RD;
+ msg[1].addr = client->addr;
+ msg[1].buf = rxBuf;
+ msg[1].len = 4;
+
+
+ i2c_transfer(client->adapter, msg, 2);
+#endif
+ *data = (rxBuf[3] << 24) | (rxBuf[2] << 16) | (rxBuf[1] << 8) | (rxBuf[0]); /*LSB fisrt*/
+ return 0;
+}
+/*----------------------------------------------------------------------------*/
+EXPORT_SYMBOL_GPL(mt8193_i2c_read);
+/*----------------------------------------------------------------------------*/
+
+int mt8193_i2c_write(u16 addr, u32 data)
+{
+ struct i2c_client *client = mt8193_i2c_client;
+ u8 buffer[8];
+ int ret = 0;
+ struct i2c_msg msg = {
+ /*.addr = client->addr & I2C_MASK_FLAG,*/
+ .addr = client->addr,
+ .flags = 0,
+ .len = (((addr >> 8) & 0xFF) >= 0x80)?5:6,
+ .buf = buffer,
+ };
+
+ if (((addr >> 8) & 0xFF) >= 0x80) {
+ /* 8 bit : fast mode */
+ buffer[0] = (addr >> 8) & 0xFF;
+ buffer[1] = (data >> 24) & 0xFF;
+ buffer[2] = (data >> 16) & 0xFF;
+ buffer[3] = (data >> 8) & 0xFF;
+ buffer[4] = data & 0xFF;
+ } else {
+ /* 16 bit : noraml mode */
+ buffer[0] = (addr >> 8) & 0xFF;
+ buffer[1] = addr & 0xFF;
+ buffer[2] = (data >> 24) & 0xFF;
+ buffer[3] = (data >> 16) & 0xFF;
+ buffer[4] = (data >> 8) & 0xFF;
+ buffer[5] = data & 0xFF;
+ }
+
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret < 0) {
+ pr_err("%s: send command error\n", __func__);
+ return -EFAULT;
+ }
+ return 0;
+}
+/*----------------------------------------------------------------------------*/
+EXPORT_SYMBOL_GPL(mt8193_i2c_write);
+
+/*----------------------------------------------------------------------------*/
+/* IIC Probe */
+/*----------------------------------------------------------------------------*/
+static int mt8193_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ int ret = -1;
+ struct mt8193_i2c_data *obj;
+
+ pr_err("%s\n", __func__);
+
+ obj = kzalloc(sizeof(*obj), GFP_KERNEL);
+ if (obj == NULL) {
+ ret = -ENOMEM;
+ pr_err("%s: Allocate ts memory fail\n", __func__);
+ return ret;
+ }
+ obj_i2c_data = obj;
+ obj->client = client;
+ mt8193_i2c_client = obj->client;
+ i2c_set_clientdata(client, obj);
+
+ return 0;
+}
+/*----------------------------------------------------------------------------*/
+
+static int mt8193_i2c_remove(struct i2c_client *client)
+{
+ pr_err("%s\n", __func__);
+ mt8193_i2c_client = NULL;
+ i2c_unregister_device(client);
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
+/*----------------------------------------------------------------------------*/
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+static int mt8193_power_init(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct device_node *kd_node = NULL;
+ struct pinctrl *rst_pinctrl;
+ struct pinctrl_state *pin_state;
+
+ mt8193_dev_context = (struct device *)&(pdev->dev);
+ kd_node = mt8193_dev_context->of_node;
+ /* get regulator supply node */
+ mt8193_dev_context->of_node = of_find_compatible_node(NULL, NULL, "mediatek,mt_pmic_regulator_supply");
+
+ pr_err("mt8193_power_init get mt_pmic_regulator_supply!\n");
+
+ if (vmipi_pmu == NULL)
+ vmipi_pmu = regulator_get(mt8193_dev_context, "vmipi");
+
+ if (IS_ERR(vmipi_pmu)) {
+ pr_err("mt8193_power_init vmipi_pmu error %p!!!!!!!!!!!!!!\n", vmipi_pmu);
+ ret = -1;
+ goto exit;
+ } else {
+ pr_debug("mt8193_power_init vmipi_pmu init done %p\n", vmipi_pmu);
+ regulator_set_voltage(vmipi_pmu, 1800000, 1800000);
+ ret = regulator_enable(vmipi_pmu);
+ if (ret)
+ pr_err("regulator_enable vmipi failed!\n");
+ else
+ pr_err("regulator_enable vmipi pass!\n");
+ }
+ udelay(4);
+
+ if (vrf12_pmu == NULL)
+ vrf12_pmu = regulator_get(mt8193_dev_context, "vrf12");
+
+ if (IS_ERR(vrf12_pmu)) {
+ pr_err("mt8193_power_init vrf12_pmu error %p!!!!!!!!!!!!!!\n", vrf12_pmu);
+ ret = -1;
+ goto vrf12_pmu_exit;
+ } else {
+ pr_debug("mt8193_power_init vrf12_pmu init done %p\n", vrf12_pmu);
+ regulator_set_voltage(vrf12_pmu, 1200000, 1200000);
+ ret = regulator_enable(vrf12_pmu);
+ if (ret)
+ pr_err("regulator_enable vrf12_pmu failed!\n");
+ else
+ pr_err("regulator_enable vrf12_pmu pass!\n");
+ }
+ udelay(8);
+
+ if (vibr_pmu == NULL)
+ vibr_pmu = regulator_get(mt8193_dev_context, "vibr");
+
+ if (IS_ERR(vibr_pmu)) {
+ pr_err("mt8193_power_init vibr_pmu error %p!!!!!!!!!!!!!!\n", vibr_pmu);
+ ret = -1;
+ goto vibr_pmu_exit;
+ } else {
+ pr_debug("mt8193_power_init vibr_pmu init done %p\n", vibr_pmu);
+ regulator_set_voltage(vibr_pmu, 3300000, 3300000);
+ ret = regulator_enable(vibr_pmu);
+ if (ret)
+ pr_err("regulator_enable vibr_pmu failed!\n");
+ else
+ pr_err("regulator_enable vibr_pmu pass!\n");
+ }
+ udelay(4);
+
+ if (vldo28_pmu == NULL)
+ vldo28_pmu = regulator_get(mt8193_dev_context, "vldo28");
+
+ if (IS_ERR(vldo28_pmu)) {
+ pr_err("mt8193_power_init vldo28_pmu error %p!!!!!!!!!!!!!!\n", vldo28_pmu);
+ ret = -1;
+ goto vldo28_pmu_exit;
+ } else {
+ pr_debug("mt8193_power_init vldo28_pmu init done %p\n", vldo28_pmu);
+ regulator_set_voltage(vldo28_pmu, 2800000, 2800000);
+ ret = regulator_enable(vldo28_pmu);
+ if (ret)
+ pr_err("regulator_enable vldo28_pmu failed!\n");
+ else
+ pr_err("regulator_enable vldo28_pmu pass!\n");
+ }
+ msleep(20);
+
+ mt8193_dev_context->of_node = kd_node;
+ rst_pinctrl = devm_pinctrl_get(mt8193_dev_context);
+ if (IS_ERR(rst_pinctrl)) {
+ ret = PTR_ERR(rst_pinctrl);
+ pr_err("Cannot find mt8193 rst pinctrl!\n");
+ goto rst_exit;
+ }
+ pin_state = pinctrl_lookup_state(rst_pinctrl, rst_pin_name[1]);
+ if (IS_ERR(pin_state)) {
+ ret = PTR_ERR(pin_state);
+ pr_err("Cannot find mt8193 rst pin state!\n");
+ goto rst_exit;
+ } else {
+ pinctrl_select_state(rst_pinctrl, pin_state);
+ }
+#if 0
+ dn = of_find_compatible_node(NULL, NULL, "mediatek,mt8193-hdmi");
+ bus_reset_pin = of_get_named_gpio(dn, "hdmi_reset_gpios", 0);
+ gpio_direction_output(bus_reset_pin, 1);
+#endif
+ return ret;
+rst_exit:
+ regulator_disable(vldo28_pmu);
+vldo28_pmu_exit:
+ regulator_disable(vibr_pmu);
+vibr_pmu_exit:
+ regulator_disable(vrf12_pmu);
+vrf12_pmu_exit:
+ regulator_disable(vmipi_pmu);
+exit:
+ mt8193_dev_context->of_node = kd_node;
+ return ret;
+}
+#endif
+/*----------------------------------------------------------------------------*/
+/* device driver probe */
+/*----------------------------------------------------------------------------*/
+static int mt8193_probe(struct platform_device *pdev)
+{
+ pr_err("%s\n", __func__);
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+ mt8193_power_init(pdev);
+#else
+ if (i2c_add_driver(&mt8193_i2c_driver)) {
+ pr_err("%s: unable to add mt8193 i2c driver\n", __func__);
+ return -1;
+ }
+#endif
+ return 0;
+}
+/*----------------------------------------------------------------------------*/
+static int mt8193_remove(struct platform_device *pdev)
+{
+ pr_err("%s\n", __func__);
+ i2c_del_driver(&mt8193_i2c_driver);
+ return 0;
+}
+/*----------------------------------------------------------------------------*/
+#ifdef CONFIG_OF
+static const struct of_device_id multibridge_of_ids[] = {
+ {.compatible = "mediatek,multibridge",},
+ {}
+};
+#endif
+
+static struct platform_driver mt8193_mb_driver = {
+ .probe = mt8193_probe,
+ .remove = mt8193_remove,
+ .driver = {
+ .name = "multibridge",
+#ifdef CONFIG_OF
+ .of_match_table = multibridge_of_ids,
+#endif
+ }
+};
+
+/*----------------------------------------------------------------------------*/
+static int __init mt8193_mb_init(void)
+{
+ int ret = 0;
+
+ pr_err("%s\n", __func__);
+#ifdef HDMI_OPEN_PACAKAGE_SUPPORT
+ if (i2c_add_driver(&mt8193_i2c_driver)) {
+ pr_err("%s: unable to add mt8193 i2c driver\n", __func__);
+ return -1;
+ }
+#endif
+ /*i2c_register_board_info(1, &i2c_mt8193, 1);*/
+ ret = platform_driver_register(&mt8193_mb_driver);
+ if (ret) {
+ pr_err("failed to register mt8193_mb_driver, ret=%d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+/*----------------------------------------------------------------------------*/
+static void __exit mt8193_mb_exit(void)
+{
+ platform_driver_unregister(&mt8193_mb_driver);
+}
+/*----------------------------------------------------------------------------*/
+#ifndef HDMI_OPEN_PACAKAGE_SUPPORT
+static int __init mt8193_i2c_board_init(void)
+{
+ int ret = 0;
+
+ pr_err("%s\n", __func__);
+ ret = i2c_register_board_info(MT8193_I2C_ID, &i2c_mt8193, 1);
+ if (ret)
+ pr_err("failed to register mt8193 i2c_board_info, ret=%d\n", ret);
+
+ return ret;
+}
+/*----------------------------------------------------------------------------*/
+core_initcall(mt8193_i2c_board_init);
+#endif
+module_init(mt8193_mb_init);
+module_exit(mt8193_mb_exit);
+MODULE_AUTHOR("SS, Wu <ss.wu@mediatek.com>");
+MODULE_DESCRIPTION("MT8193 Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_pinmux.c b/drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_pinmux.c
new file mode 100644
index 000000000000..2ff2c3781ae4
--- /dev/null
+++ b/drivers/misc/mediatek/multibridge/mt6797/mt8193/mt8193_pinmux.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#if defined(CONFIG_MTK_MULTIBRIDGE_SUPPORT)
+
+#define pr_fmt(fmt) "mt8193-pinmux: " fmt
+
+#include <generated/autoconf.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/kthread.h>
+#include <linux/vmalloc.h>
+
+#include <linux/uaccess.h>
+#include <linux/atomic.h>
+#include <asm/cacheflush.h>
+#include <linux/io.h>
+
+#include <mach/irqs.h>
+
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/mm.h>
+#include <linux/cdev.h>
+#include <asm/tlbflush.h>
+#include <asm/page.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+
+#include <generated/autoconf.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/kthread.h>
+
+#include <linux/uaccess.h>
+#include <linux/atomic.h>
+#include <asm/cacheflush.h>
+#include <linux/io.h>
+
+#include <mach/irqs.h>
+#include <linux/vmalloc.h>
+
+#include <linux/uaccess.h>
+
+#include "mt8193_pinmux.h"
+#include "mt8193.h"
+
+
+/* select function according to pinmux table */
+int mt8193_pinset(u32 pin_num, u32 function)
+{
+ u32 pin_mux_val = 0;
+ u32 pin_mux_reg = 0;
+ u32 pin_mux_mask = 0;
+ u32 pin_mux_shift = 0;
+
+ if (pin_num >= PIN_MAX) {
+ pr_err("[PINMUX] INVALID PINMUX!! %d\n", pin_num);
+ return -1;
+ }
+ if (function >= PINMUX_FUNCTION_MAX) {
+ pr_err("[PINMUX] INVALID FUNCTION NUM!! %d\n", function);
+ return -1;
+ }
+
+ pr_debug("[PINMUX] mt8193_pinset() %d, %d\n", pin_num, function);
+
+ pin_mux_reg = _au4PinmuxFuncTbl[pin_num][0]; /* pinmux register */
+ pin_mux_shift = _au4PinmuxFuncTbl[pin_num][1]; /*pinmux left shift */
+ pin_mux_mask = _au4PinmuxFuncTbl[pin_num][2]; /* pinmux mask */
+
+ pin_mux_val = CKGEN_READ32(pin_mux_reg);
+
+ /* clear function first*/
+ pin_mux_val &= (~pin_mux_mask);
+ /* set function */
+ pin_mux_val |= ((function << pin_mux_shift) & pin_mux_mask);
+ CKGEN_WRITE32(pin_mux_reg, pin_mux_val);
+
+ return PINMUX_RET_OK;
+}
+
+#endif
+
+
+
+
+
diff --git a/drivers/misc/mediatek/video/mt6797/dispsys/ddp_dpi.c b/drivers/misc/mediatek/video/mt6797/dispsys/ddp_dpi.c
index 9b3cfead222f..4a7d8aa8252d 100644
--- a/drivers/misc/mediatek/video/mt6797/dispsys/ddp_dpi.c
+++ b/drivers/misc/mediatek/video/mt6797/dispsys/ddp_dpi.c
@@ -445,6 +445,70 @@ enum DPI_STATUS ddp_dpi_ConfigSize(cmdqRecHandle cmdq, unsigned width, unsigned
return DPI_STATUS_OK;
}
+#ifdef HDMI_MT8193_SUPPORT
+enum DPI_STATUS ddp_dpi_ConfigCCIR656(cmdqRecHandle cmdq, bool enable)
+{
+ struct DPI_REG_CNTL csc = DPI_REG->CNTL;
+ struct DPI_REG_OUTPUT_SETTING outputsetting = DPI_REG->OUTPUT_SETTING;
+ struct DPI_REG_Y_LIMIT ylimit = DPI_REG->Y_LIMIT;
+ struct DPI_REG_C_LIMIT climit = DPI_REG->C_LIMIT;
+ struct DPI_REG_YUV422_SETTING yuv422setting = DPI_REG->YUV422_SETTING;
+ struct DPI_REG_EMBSYNC_SETTING embsync = DPI_REG->EMBSYNC_SETTING;
+ struct DPI_REG_ESAV_VTIM_LOAD esavtimload = DPI_REG->ESAV_VTIM_LOAD;
+
+
+ if (enable == FALSE)
+ return DPI_STATUS_OK;
+
+ csc.YUV422_EN = 1;
+ csc.RGB2YUV_EN = 1;
+ csc.EMBSYNC_EN = 1;
+
+ DPI_OUTREGBIT(cmdq, struct DPI_REG_CNTL, DPI_REG->CNTL, YUV422_EN, csc.YUV422_EN);
+ DPI_OUTREGBIT(cmdq, struct DPI_REG_CNTL, DPI_REG->CNTL, RGB2YUV_EN, csc.RGB2YUV_EN);
+ DPI_OUTREGBIT(cmdq, struct DPI_REG_CNTL, DPI_REG->CNTL, EMBSYNC_EN, csc.EMBSYNC_EN);
+
+ outputsetting.YC_MAP = 7;
+ outputsetting.CLK_POL = 1;
+
+ DPI_OUTREGBIT(cmdq, struct DPI_REG_OUTPUT_SETTING, DPI_REG->OUTPUT_SETTING, YC_MAP, outputsetting.YC_MAP);
+ DPI_OUTREGBIT(cmdq, struct DPI_REG_OUTPUT_SETTING, DPI_REG->OUTPUT_SETTING, CLK_POL, outputsetting.CLK_POL);
+
+ ylimit.Y_LIMIT_BOT = 0x100;
+ ylimit.Y_LIMIT_TOP = 0xF00;
+ climit.C_LIMIT_BOT = 0x100;
+ climit.C_LIMIT_TOP = 0xF00;
+
+ DPI_OUTREGBIT(cmdq, struct DPI_REG_Y_LIMIT, DPI_REG->Y_LIMIT, Y_LIMIT_BOT, ylimit.Y_LIMIT_BOT);
+ DPI_OUTREGBIT(cmdq, struct DPI_REG_Y_LIMIT, DPI_REG->Y_LIMIT, Y_LIMIT_TOP, ylimit.Y_LIMIT_TOP);
+ DPI_OUTREGBIT(cmdq, struct DPI_REG_C_LIMIT, DPI_REG->C_LIMIT, C_LIMIT_BOT, climit.C_LIMIT_BOT);
+ DPI_OUTREGBIT(cmdq, struct DPI_REG_C_LIMIT, DPI_REG->C_LIMIT, C_LIMIT_TOP, climit.C_LIMIT_TOP);
+
+ yuv422setting.UV_SWAP = 1;
+
+ DPI_OUTREGBIT(cmdq, struct DPI_REG_YUV422_SETTING, DPI_REG->YUV422_SETTING, UV_SWAP, yuv422setting.UV_SWAP);
+
+ embsync.EMBVSYNC_R_CR = 1;
+ embsync.EMBVSYNC_G_Y = 1;
+ embsync.EMBVSYNC_B_CB = 1;
+
+ DPI_OUTREGBIT(cmdq, struct DPI_REG_EMBSYNC_SETTING, DPI_REG->EMBSYNC_SETTING,
+ EMBVSYNC_R_CR, embsync.EMBVSYNC_R_CR);
+ DPI_OUTREGBIT(cmdq, struct DPI_REG_EMBSYNC_SETTING, DPI_REG->EMBSYNC_SETTING,
+ EMBVSYNC_G_Y, embsync.EMBVSYNC_G_Y);
+ DPI_OUTREGBIT(cmdq, struct DPI_REG_EMBSYNC_SETTING, DPI_REG->EMBSYNC_SETTING,
+ EMBVSYNC_B_CB, embsync.EMBVSYNC_B_CB);
+
+ esavtimload.ESAV_VWID_LODD = 0x1E;
+
+ DPI_OUTREGBIT(cmdq, struct DPI_REG_ESAV_VTIM_LOAD, DPI_REG->ESAV_VTIM_LOAD,
+ ESAV_VWID_LODD, esavtimload.ESAV_VWID_LODD);
+
+
+ return DPI_STATUS_OK;
+}
+#endif
+
enum DPI_STATUS ddp_dpi_EnableColorBar(void)
{
/*enable internal pattern - color bar */
@@ -546,6 +610,9 @@ int ddp_dpi_config(DISP_MODULE_ENUM module, disp_ddp_path_config *config, void *
ddp_dpi_ConfigDualEdge(cmdq_handle, dpi_config->i2x_en, dpi_config->i2x_edge);
+#ifdef HDMI_MT8193_SUPPORT
+ ddp_dpi_ConfigCCIR656(cmdq_handle, TRUE);
+#endif
s_isDpiConfig = TRUE;
pr_warn("DISP/DPI,ddp_dpi_config done\n");
}