diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0805fa41ac9b7224d97a57cfd968840125732831..30ed279474bc792eb707663e43a6bd33641fed99 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -442,7 +442,6 @@ config TARGET_BCMNSP
 
 config ARCH_EXYNOS
 	bool "Samsung EXYNOS"
-	select CPU_V7
 	select DM
 	select DM_SPI_FLASH
 	select DM_SERIAL
diff --git a/arch/arm/cpu/armv7/s5p-common/timer.c b/arch/arm/cpu/armv7/s5p-common/timer.c
index 949abb1c8fe58fa980e1f3830dca615419003b6c..b63036c64eb1427f4a0da145d0cf3dfaf4193e63 100644
--- a/arch/arm/cpu/armv7/s5p-common/timer.c
+++ b/arch/arm/cpu/armv7/s5p-common/timer.c
@@ -12,6 +12,9 @@
 #include <asm/io.h>
 #include <asm/arch/pwm.h>
 #include <asm/arch/clk.h>
+
+/* Use the old PWM interface for now */
+#undef CONFIG_DM_PWM
 #include <pwm.h>
 
 DECLARE_GLOBAL_DATA_PTR;
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 1814797b1c3418c06232e75186197f3acdc68ec3..a8276138ab1849481e34098d06202418231e9849 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -21,6 +21,7 @@ dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \
 	exynos5420-peach-pit.dtb \
 	exynos5800-peach-pi.dtb \
 	exynos5422-odroidxu3.dtb
+dtb-$(CONFIG_EXYNOS7420) += exynos7420-espresso7420.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += \
 	rk3288-firefly.dtb \
 	rk3288-jerry.dtb \
diff --git a/arch/arm/dts/exynos5.dtsi b/arch/arm/dts/exynos5.dtsi
index 179584c7487c67a552d6b23da269ced32ad2861f..8650800f5201c62f40ab7cec30499730ceba11c1 100644
--- a/arch/arm/dts/exynos5.dtsi
+++ b/arch/arm/dts/exynos5.dtsi
@@ -163,13 +163,14 @@
 	};
 
 	fimd@14400000 {
+		u-boot,dm-pre-reloc;
 		compatible = "samsung,exynos-fimd";
 		reg = <0x14400000 0x10000>;
 		#address-cells = <1>;
 		#size-cells = <1>;
 	};
 
-	dp@145b0000 {
+	dp: dp@145b0000 {
 		compatible = "samsung,exynos5-dp";
 		reg = <0x145b0000 0x1000>;
 		#address-cells = <1>;
diff --git a/arch/arm/dts/exynos5250-snow.dts b/arch/arm/dts/exynos5250-snow.dts
index bda549998861c65b6cfd66c9c29a4fc68996c3fb..29c13c1257e7773fe20c07a42c887b768100a875 100644
--- a/arch/arm/dts/exynos5250-snow.dts
+++ b/arch/arm/dts/exynos5250-snow.dts
@@ -198,6 +198,20 @@
 			reset-gpios = <&gpx1 5 GPIO_ACTIVE_LOW>;
 			hotplug-gpios = <&gpx0 7 GPIO_ACTIVE_HIGH>;
 			edid-emulation = <5>;
+
+			ports {
+				port@0 {
+					bridge_out: endpoint {
+						remote-endpoint = <&panel_in>;
+					};
+				};
+
+				port@1 {
+					bridge_in: endpoint {
+						remote-endpoint = <&dp_out>;
+					};
+				};
+			};
 		};
 
 		soundcodec@22 {
@@ -223,6 +237,27 @@
 		};
 	};
 
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm 0 1000000 0>;
+		brightness-levels = <0 100 500 1000 1500 2000 2500 2800>;
+		default-brightness-level = <7>;
+		enable-gpios = <&gpx3 0 GPIO_ACTIVE_HIGH>;
+		power-supply = <&fet1>;
+	};
+
+	panel: panel {
+		compatible = "auo,b116xw03";
+		power-supply = <&fet6>;
+		backlight = <&backlight>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&bridge_out>;
+			};
+		};
+	};
+
 	spi@131b0000 {
 		spi-max-frequency = <1000000>;
 		spi-deactivate-delay = <100>;
@@ -337,6 +372,15 @@
 		samsung,dynamic-range = <0>;
 		samsung,ycbcr-coeff = <0>;
 		samsung,color-depth = <1>;
+		samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>;
+
+		ports {
+			port@0 {
+				dp_out: endpoint {
+					remote-endpoint = <&bridge_in>;
+				};
+			};
+		};
 	};
 
 };
diff --git a/arch/arm/dts/exynos5250-spring.dts b/arch/arm/dts/exynos5250-spring.dts
index 81b3d29f9cf032d962f1e41c8dc0168e8079d654..693501e4c19ca8d7cf95aa798d97e12e4026be5d 100644
--- a/arch/arm/dts/exynos5250-spring.dts
+++ b/arch/arm/dts/exynos5250-spring.dts
@@ -158,6 +158,27 @@
 		samsung,ycbcr-coeff = <0>;
 		samsung,color-depth = <1>;
 	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm 0 1000000 0>;
+		brightness-levels = <0 100 500 1000 1500 2000 2500 2800>;
+		default-brightness-level = <1>;
+		enable-gpios = <&gpx3 0 GPIO_ACTIVE_HIGH>;
+		power-supply = <&fet1>;
+	};
+
+	panel: panel {
+		compatible = "auo,b116xw03";
+		power-supply = <&fet6>;
+		backlight = <&backlight>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&bridge_out>;
+			};
+		};
+	};
 };
 
 &i2c_0 {
@@ -385,6 +406,25 @@
 	};
 };
 
+&dp {
+	status = "okay";
+	samsung,color-space = <0>;
+	samsung,dynamic-range = <0>;
+	samsung,ycbcr-coeff = <0>;
+	samsung,color-depth = <1>;
+	samsung,link-rate = <0x0a>;
+	samsung,lane-count = <1>;
+	samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>;
+
+	ports {
+		port@0 {
+			dp_out: endpoint {
+				remote-endpoint = <&bridge_in>;
+			};
+		};
+	};
+};
+
 &i2c_1 {
 	status = "okay";
 	samsung,i2c-sda-delay = <100>;
@@ -585,6 +625,19 @@
 			0x04 0x59 0x60 /* MPU Clock source: LC => RCO */
 			0x04 0x54 0x14 /* LC -> RCO */
 			0x02 0xa1 0x91>; /* HPD high */
+		ports {
+			port@0 {
+				bridge_out: endpoint {
+					remote-endpoint = <&panel_in>;
+				};
+			};
+
+			port@1 {
+				bridge_in: endpoint {
+					remote-endpoint = <&dp_out>;
+				};
+			};
+		};
 	};
 
 	soundcodec@20 {
diff --git a/arch/arm/dts/exynos5250.dtsi b/arch/arm/dts/exynos5250.dtsi
index 7eef3e3f4fb78fa280c6135697a075fb38eaa061..d44c9f647ee74184e8c96741af072c7373a7236c 100644
--- a/arch/arm/dts/exynos5250.dtsi
+++ b/arch/arm/dts/exynos5250.dtsi
@@ -116,4 +116,11 @@
 		};
 	};
 
+	pwm: pwm@12dd0000 {
+		compatible = "samsung,exynos4210-pwm";
+		reg = <0x12dd0000 0x100>;
+		samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+		#pwm-cells = <3>;
+	};
+
 };
diff --git a/arch/arm/dts/exynos5420-peach-pit.dts b/arch/arm/dts/exynos5420-peach-pit.dts
index 16d52f4928121afce9ca12c4d263c6ae6ddfea67..2db4ad2dbd0a98f774c1449a30b96da4cd6cf8ea 100644
--- a/arch/arm/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/dts/exynos5420-peach-pit.dts
@@ -9,6 +9,8 @@
 
 /dts-v1/;
 #include "exynos54xx.dtsi"
+#include <dt-bindings/clock/maxim,max77802.h>
+#include <dt-bindings/regulator/maxim,max77802.h>
 
 / {
 	model = "Samsung/Google Peach Pit board based on Exynos5420";
@@ -29,6 +31,14 @@
 		i2c104 = &i2c_tunnel;
 	};
 
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm 0 1000000 0>;
+		brightness-levels = <0 100 500 1000 1500 2000 2500 2800>;
+		default-brightness-level = <7>;
+		power-supply = <&tps65090_fet1>;
+	};
+
 	dmc {
 		mem-manuf = "samsung";
 		mem-type = "ddr3";
@@ -188,6 +198,20 @@
 				0x04 0x59 0x60
 				0x04 0x54 0x14  /* LC -> RCO */
 				0x02 0xa1 0x91>;  /* HPD high */
+
+			ports {
+				port@0 {
+					bridge_out: endpoint {
+						remote-endpoint = <&panel_in>;
+					};
+				};
+
+				port@1 {
+					bridge_in: endpoint {
+						remote-endpoint = <&dp_out>;
+					};
+				};
+			};
 	        };
 	};
 
@@ -203,6 +227,18 @@
 		};
 	};
 
+	panel: panel {
+		compatible = "auo,b116xw03";
+		power-supply = <&tps65090_fet6>;
+		backlight = <&backlight>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&bridge_out>;
+			};
+		};
+	};
+
 	spi@12d30000 { /* spi1 */
 		spi-max-frequency = <50000000>;
 		firmware_storage_spi: flash@0 {
@@ -254,6 +290,25 @@
 	};
 };
 
+&dp {
+	status = "okay";
+	samsung,color-space = <0>;
+	samsung,dynamic-range = <0>;
+	samsung,ycbcr-coeff = <0>;
+	samsung,color-depth = <1>;
+	samsung,link-rate = <0x06>;
+	samsung,lane-count = <2>;
+	samsung,hpd-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
+
+	ports {
+		port@0 {
+			dp_out: endpoint {
+				remote-endpoint = <&bridge_in>;
+			};
+		};
+	};
+};
+
 &spi_2 {
 	spi-max-frequency = <3125000>;
 	spi-deactivate-delay = <200>;
diff --git a/arch/arm/dts/exynos54xx.dtsi b/arch/arm/dts/exynos54xx.dtsi
index daa6a33c5b5501566d399be0bb29700f5b301dad..b4ddf53a2ec18ed64336046252f4b6afb818c8e4 100644
--- a/arch/arm/dts/exynos54xx.dtsi
+++ b/arch/arm/dts/exynos54xx.dtsi
@@ -49,7 +49,7 @@
 		status = "disabled";
 	};
 
-	i2c@12CA0000 {
+	hsi2c_4: i2c@12CA0000 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		compatible = "samsung,exynos5-hsi2c";
@@ -178,7 +178,7 @@
 		samsung,pwm-out-gpio = <&gpb2 0 GPIO_ACTIVE_HIGH>;
 	};
 
-	dp@145b0000 {
+	dp: dp@145b0000 {
 		samsung,lt-status = <0>;
 
 		samsung,master-mode = <0>;
@@ -197,6 +197,13 @@
 		mem-type = "ddr3";
 	};
 
+	pwm: pwm@12dd0000 {
+		compatible = "samsung,exynos4210-pwm";
+		reg = <0x12dd0000 0x100>;
+		samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+		#pwm-cells = <3>;
+	};
+
 	xhci1: xhci@12400000 {
 		compatible = "samsung,exynos5250-xhci";
 		reg = <0x12400000 0x10000>;
diff --git a/arch/arm/dts/exynos5800-peach-pi.dts b/arch/arm/dts/exynos5800-peach-pi.dts
index 76826dc23b92c3b69f4eda5887793968a0078b98..4c139bf143a5aff64923e15573b185cf4347f1f1 100644
--- a/arch/arm/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/dts/exynos5800-peach-pi.dts
@@ -30,6 +30,27 @@
 		i2c104 = &i2c_tunnel;
 	};
 
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm 0 1000000 0>;
+		brightness-levels = <0 100 500 1000 1500 2000 2500 2800>;
+		default-brightness-level = <7>;
+		enable-gpios = <&gpx2 2 GPIO_ACTIVE_HIGH>;
+		power-supply = <&tps65090_fet1>;
+	};
+
+	panel: panel {
+		compatible = "auo,b133htn01";
+		power-supply = <&tps65090_fet6>;
+		backlight = <&backlight>;
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&dp_out>;
+			};
+		};
+	};
+
 	dmc {
 		mem-manuf = "samsung";
 		mem-type = "ddr3";
@@ -132,6 +153,25 @@
 	};
 };
 
+&dp {
+	status = "okay";
+	samsung,color-space = <0>;
+	samsung,dynamic-range = <0>;
+	samsung,ycbcr-coeff = <0>;
+	samsung,color-depth = <1>;
+	samsung,link-rate = <0x0a>;
+	samsung,lane-count = <2>;
+	samsung,hpd-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
+
+	ports {
+		port {
+			dp_out: endpoint {
+				remote-endpoint = <&panel_in>;
+			};
+		};
+	};
+};
+
 &spi_2 {
 	spi-max-frequency = <3125000>;
 	spi-deactivate-delay = <200>;
diff --git a/arch/arm/dts/exynos7420-espresso7420.dts b/arch/arm/dts/exynos7420-espresso7420.dts
new file mode 100644
index 0000000000000000000000000000000000000000..f17a8482ff4170791a671aeb39e4e9d083875715
--- /dev/null
+++ b/arch/arm/dts/exynos7420-espresso7420.dts
@@ -0,0 +1,24 @@
+/*
+ * Samsung Espresso7420 board device tree source
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include "exynos7420.dtsi"
+/ {
+	model = "Samsung Espresso7420 board based on Exynos7420";
+	compatible = "samsung,espresso7420", "samsung,exynos7420";
+
+	aliases {
+		serial2 = "/serial@14C30000";
+		console = "/serial@14C30000";
+		pinctrl0 = "/pinctrl@13470000";
+	};
+};
+
+&fin_pll {
+	clock-frequency = <24000000>;
+};
diff --git a/arch/arm/dts/exynos7420.dtsi b/arch/arm/dts/exynos7420.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..b398021e3082fb92a7d4abb4df91067e9163e68d
--- /dev/null
+++ b/arch/arm/dts/exynos7420.dtsi
@@ -0,0 +1,83 @@
+/*
+ * Samsung Exynos7420 SoC device tree source
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+/dts-v1/;
+#include "skeleton.dtsi"
+#include <dt-bindings/clock/exynos7420-clk.h>
+/ {
+	compatible = "samsung,exynos7420";
+
+	fin_pll: xxti {
+		compatible = "fixed-clock";
+		clock-output-names = "fin_pll";
+		u-boot,dm-pre-reloc;
+		#clock-cells = <0>;
+	};
+
+	clock_topc: clock-controller@10570000 {
+		compatible = "samsung,exynos7-clock-topc";
+		reg = <0x10570000 0x10000>;
+		u-boot,dm-pre-reloc;
+		#clock-cells = <1>;
+		clocks = <&fin_pll>;
+		clock-names = "fin_pll";
+	};
+
+	clock_top0: clock-controller@105d0000 {
+		compatible = "samsung,exynos7-clock-top0";
+		reg = <0x105d0000 0xb000>;
+		u-boot,dm-pre-reloc;
+		#clock-cells = <1>;
+		clocks = <&fin_pll>, <&clock_topc DOUT_SCLK_BUS0_PLL>,
+			 <&clock_topc DOUT_SCLK_BUS1_PLL>,
+			 <&clock_topc DOUT_SCLK_CC_PLL>,
+			 <&clock_topc DOUT_SCLK_MFC_PLL>;
+		clock-names = "fin_pll", "dout_sclk_bus0_pll",
+			      "dout_sclk_bus1_pll", "dout_sclk_cc_pll",
+			      "dout_sclk_mfc_pll";
+	};
+
+	clock_peric1: clock-controller@14c80000 {
+		compatible = "samsung,exynos7-clock-peric1";
+		reg = <0x14c80000 0xd00>;
+		u-boot,dm-pre-reloc;
+		#clock-cells = <1>;
+		clocks = <&fin_pll>, <&clock_top0 DOUT_ACLK_PERIC1>,
+			 <&clock_top0 CLK_SCLK_UART1>,
+			 <&clock_top0 CLK_SCLK_UART2>,
+			 <&clock_top0 CLK_SCLK_UART3>;
+		clock-names = "fin_pll", "dout_aclk_peric1_66",
+			      "sclk_uart1", "sclk_uart2", "sclk_uart3";
+	};
+
+	pinctrl@13470000 {
+		compatible = "samsung,exynos7420-pinctrl";
+		reg = <0x13470000 0x1000>;
+		u-boot,dm-pre-reloc;
+
+		serial2_bus: serial2-bus {
+			samsung,pins = "gpd1-4", "gpd1-5";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <3>;
+			samsung,pin-drv = <0>;
+			u-boot,dm-pre-reloc;
+		};
+	};
+
+	serial@14C30000 {
+		compatible = "samsung,exynos4210-uart";
+		reg = <0x14C30000 0x100>;
+		u-boot,dm-pre-reloc;
+		clocks = <&clock_peric1 PCLK_UART2>,
+			 <&clock_peric1 SCLK_UART2>;
+		clock-names = "uart", "clk_uart_baud0";
+		pinctrl-names = "default";
+		pinctrl-0 = <&serial2_bus>;
+	};
+};
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index a6a75974d7321080c655ef7539e5556c9f554933..c25fcf3f9f2d7534c454dadb3a6e9c821ddec393 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -1,9 +1,40 @@
 if ARCH_EXYNOS
 
 choice
-	prompt "EXYNOS board select"
+	prompt "EXYNOS architecture type select"
 	optional
 
+config ARCH_EXYNOS4
+	bool "Exynos4 SoC family"
+	select CPU_V7
+	help
+	  Samsung Exynos4 SoC family are based on ARM Cortex-A9 CPU. There
+	  are multiple SoCs in this family including Exynos4210, Exynos4412,
+	  and Exynos4212.
+
+config ARCH_EXYNOS5
+	bool "Exynos5 SoC family"
+	select CPU_V7
+	help
+	  Samsung Exynos5 SoC family are based on ARM Cortex-A15 CPU (and
+	  Cortex-A7 CPU in big.LITTLE configuration). There are multiple SoCs
+	  in this family including Exynos5250, Exynos5420 and Exynos5800.
+
+config ARCH_EXYNOS7
+	bool "Exynos7 SoC family"
+	select ARM64
+	help
+	  Samsung Exynos7 SoC family are based on ARM Cortex-A57 CPU or
+	  Cortex-A53 CPU (and some in a big.LITTLE configuration). There are
+	  multiple SoCs in this family including Exynos7420.
+
+endchoice
+
+if ARCH_EXYNOS4
+
+choice
+	prompt "EXYNOS4 board select"
+
 config TARGET_SMDKV310
 	select SUPPORT_SPL
 	bool "Exynos4210 SMDKV310 board"
@@ -25,6 +56,14 @@ config TARGET_TRATS2
 config TARGET_ODROID
 	bool "Exynos4412 Odroid board"
 
+endchoice
+endif
+
+if ARCH_EXYNOS5
+
+choice
+	prompt "EXYNOS5 board select"
+
 config TARGET_ODROID_XU3
 	bool "Exynos5422 Odroid board"
 	select OF_CONTROL
@@ -68,6 +107,25 @@ config TARGET_PEACH_PIT
 	select OF_CONTROL
 
 endchoice
+endif
+
+if ARCH_EXYNOS7
+
+choice
+	prompt "EXYNOS7 board select"
+
+config  TARGET_ESPRESSO7420
+	bool "ESPRESSO7420 board"
+	select ARM64
+	select SUPPORT_SPL
+	select OF_CONTROL
+	select SPL_DISABLE_OF_CONTROL
+	select PINCTRL
+	select PINCTRL_EXYNOS7420
+	select CLK_EXYNOS
+
+endchoice
+endif
 
 config SYS_SOC
 	default "exynos"
@@ -81,5 +139,6 @@ source "board/samsung/odroid/Kconfig"
 source "board/samsung/arndale/Kconfig"
 source "board/samsung/smdk5250/Kconfig"
 source "board/samsung/smdk5420/Kconfig"
+source "board/samsung/espresso7420/Kconfig"
 
 endif
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 8542f896cfc9228f598781b376ba11e4f0da13d7..0cc6c3253acb4660cc841becbe565f70e9e73894 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -5,7 +5,9 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-y	+= clock.o power.o soc.o system.o pinmux.o tzpc.o
+obj-y	+= soc.o
+obj-$(CONFIG_CPU_V7) += clock.o pinmux.o power.o system.o
+obj-$(CONFIG_ARM64)	+= mmu-arm64.o
 
 obj-$(CONFIG_EXYNOS5420)	+= sec_boot.o
 
@@ -13,6 +15,6 @@ ifdef CONFIG_SPL_BUILD
 obj-$(CONFIG_EXYNOS5)	+= clock_init_exynos5.o
 obj-$(CONFIG_EXYNOS5)	+= dmc_common.o dmc_init_ddr3.o
 obj-$(CONFIG_EXYNOS4210)+= dmc_init_exynos4.o clock_init_exynos4.o
-obj-y	+= spl_boot.o
+obj-y	+= spl_boot.o tzpc.o
 obj-y	+= lowlevel_init.o
 endif
diff --git a/arch/arm/mach-exynos/include/mach/cpu.h b/arch/arm/mach-exynos/include/mach/cpu.h
index 14a1692467de9a0a8c407b1019c2a4dd05ee5646..1f722df9dd9fcfdc0a8cff1580d415b267c150af 100644
--- a/arch/arm/mach-exynos/include/mach/cpu.h
+++ b/arch/arm/mach-exynos/include/mach/cpu.h
@@ -270,7 +270,7 @@ IS_EXYNOS_TYPE(exynos5420, 0x5420)
 IS_EXYNOS_TYPE(exynos5422, 0x5422)
 
 #define SAMSUNG_BASE(device, base)				\
-static inline unsigned int __attribute__((no_instrument_function)) \
+static inline unsigned long __attribute__((no_instrument_function)) \
 	samsung_get_base_##device(void) \
 {								\
 	if (cpu_is_exynos4()) {				\
@@ -288,9 +288,7 @@ static inline unsigned int __attribute__((no_instrument_function)) \
 SAMSUNG_BASE(adc, ADC_BASE)
 SAMSUNG_BASE(clock, CLOCK_BASE)
 SAMSUNG_BASE(ace_sfr, ACE_SFR_BASE)
-SAMSUNG_BASE(dp, DP_BASE)
 SAMSUNG_BASE(sysreg, SYSREG_BASE)
-SAMSUNG_BASE(fimd, FIMD_BASE)
 SAMSUNG_BASE(i2c, I2C_BASE)
 SAMSUNG_BASE(i2s, I2S_BASE)
 SAMSUNG_BASE(mipi_dsim, MIPI_DSIM_BASE)
diff --git a/arch/arm/mach-exynos/include/mach/dp_info.h b/arch/arm/mach-exynos/include/mach/dp_info.h
index 17e8f56d904b99e45ca4db26bb1e23b124d33299..1079e1ef1e0bb280ce009d5df75cbc5ab23970a2 100644
--- a/arch/arm/mach-exynos/include/mach/dp_info.h
+++ b/arch/arm/mach-exynos/include/mach/dp_info.h
@@ -61,7 +61,7 @@ struct edp_video_info {
 	unsigned int color_depth;
 };
 
-struct edp_device_info {
+struct exynos_dp_priv {
 	struct edp_disp_info disp_info;
 	struct edp_link_train_info lt_info;
 	struct edp_video_info video_info;
@@ -72,6 +72,7 @@ struct edp_device_info {
 	unsigned char dpcd_rev;
 	/*support enhanced frame cap */
 	unsigned char dpcd_efc;
+	struct exynos_dp *regs;
 };
 
 enum analog_power_block {
@@ -185,7 +186,7 @@ enum {
 
 
 struct exynos_dp_platform_data {
-	struct edp_device_info *edp_dev_info;
+	struct exynos_dp_priv *edp_dev_info;
 };
 
 #ifdef CONFIG_EXYNOS_DP
diff --git a/arch/arm/mach-exynos/include/mach/gpio.h b/arch/arm/mach-exynos/include/mach/gpio.h
index 7fc8e61f9ca8e9b070f2d120e1dd3960f1566600..81363bd947a1fb43d92d7a62b32ec541efb4dbd4 100644
--- a/arch/arm/mach-exynos/include/mach/gpio.h
+++ b/arch/arm/mach-exynos/include/mach/gpio.h
@@ -1349,7 +1349,7 @@ enum exynos5420_gpio_pin {
 };
 
 struct gpio_info {
-	unsigned int reg_addr;	/* Address of register for this part */
+	unsigned long reg_addr;	/* Address of register for this part */
 	unsigned int max_gpio;	/* Maximum GPIO in this part */
 };
 
diff --git a/arch/arm/mach-exynos/include/mach/mipi_dsim.h b/arch/arm/mach-exynos/include/mach/mipi_dsim.h
index c9e8e067d741dc7fc9203d77cac3139f189f449e..43b5c017fe6599d46a4a89c3d31353bf51d6c586 100644
--- a/arch/arm/mach-exynos/include/mach/mipi_dsim.h
+++ b/arch/arm/mach-exynos/include/mach/mipi_dsim.h
@@ -320,7 +320,7 @@ struct mipi_dsim_lcd_device {
 	int			reverse_panel;
 
 	struct mipi_dsim_device *master;
-	void			*platform_data;
+	struct exynos_platform_mipi_dsim *platform_data;
 };
 
 /*
@@ -347,9 +347,10 @@ struct mipi_dsim_lcd_driver {
 };
 
 #ifdef CONFIG_EXYNOS_MIPI_DSIM
-int exynos_mipi_dsi_init(void);
+int exynos_mipi_dsi_init(struct exynos_platform_mipi_dsim *dsim_pd);
 #else
-static inline int exynos_mipi_dsi_init(void)
+static inline int exynos_mipi_dsi_init(
+			struct exynos_platform_mipi_dsim *dsim_pd)
 {
 	return 0;
 }
@@ -369,7 +370,8 @@ int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device
 						*lcd_dev);
 
 void exynos_set_dsim_platform_data(struct exynos_platform_mipi_dsim *pd);
-void exynos_init_dsim_platform_data(vidinfo_t *vid);
+struct vidinfo;
+void exynos_init_dsim_platform_data(struct vidinfo *vid);
 
 /* panel driver init based on mipi dsi interface */
 void s6e8ax0_init(void);
diff --git a/arch/arm/mach-exynos/include/mach/power.h b/arch/arm/mach-exynos/include/mach/power.h
index 3f97b31aeada2dcf20554894d338e7be47d77c4a..88f70d97a98ae742de9a0bf98f70d7d39aabc412 100644
--- a/arch/arm/mach-exynos/include/mach/power.h
+++ b/arch/arm/mach-exynos/include/mach/power.h
@@ -1717,7 +1717,7 @@ void set_usbdrd_phy_ctrl(unsigned int enable);
 #define POWER_USB_DRD_PHY_CTRL_EN		(1 << 0)
 #define POWER_USB_DRD_PHY_CTRL_DISABLE		(0 << 0)
 
-void set_dp_phy_ctrl(unsigned int enable);
+void exynos_dp_phy_ctrl(unsigned int enable);
 
 #define EXYNOS_DP_PHY_ENABLE		(1 << 0)
 
diff --git a/arch/arm/mach-exynos/lowlevel_init.c b/arch/arm/mach-exynos/lowlevel_init.c
index 6c39cb2052f94aabba313f3ec35275388945d4ee..1e090fd63ca1ab90087b97c13f9582d25a0db343 100644
--- a/arch/arm/mach-exynos/lowlevel_init.c
+++ b/arch/arm/mach-exynos/lowlevel_init.c
@@ -216,8 +216,11 @@ int do_lowlevel_init(void)
 	if (actions & DO_CLOCKS) {
 		system_clock_init();
 #ifdef CONFIG_DEBUG_UART
+#if (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SERIAL_SUPPORT)) || \
+    !defined(CONFIG_SPL_BUILD)
 		exynos_pinmux_config(PERIPH_ID_UART3, PINMUX_FLAG_NONE);
 		debug_uart_init();
+#endif
 #endif
 		mem_ctrl_init(actions & DO_MEM_RESET);
 		tzpc_init();
diff --git a/arch/arm/mach-exynos/mmu-arm64.c b/arch/arm/mach-exynos/mmu-arm64.c
new file mode 100644
index 0000000000000000000000000000000000000000..ba6d99d329d515e855d0c7084350e41add1e42a5
--- /dev/null
+++ b/arch/arm/mach-exynos/mmu-arm64.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 Samsung Electronics
+ * Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/armv8/mmu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_EXYNOS7420
+static struct mm_region exynos7420_mem_map[] = {
+	{
+		.base	= 0x10000000UL,
+		.size	= 0x10000000UL,
+		.attrs	= PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+				PTE_BLOCK_NON_SHARE |
+				PTE_BLOCK_PXN | PTE_BLOCK_UXN,
+	}, {
+		.base	= 0x40000000UL,
+		.size	= 0x80000000UL,
+		.attrs	= PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+				PTE_BLOCK_INNER_SHARE,
+	}, {
+		/* List terminator */
+		.base	= 0,
+		.size	= 0,
+		.attrs	= 0,
+	},
+};
+
+struct mm_region *mem_map = exynos7420_mem_map;
+#endif
diff --git a/arch/arm/mach-exynos/pinmux.c b/arch/arm/mach-exynos/pinmux.c
index 12eb79cb0cba417cf9bdcdfb1abefbbdd02c62b3..fec2df9bd95013826d4e75e346835e3c97f6ce89 100644
--- a/arch/arm/mach-exynos/pinmux.c
+++ b/arch/arm/mach-exynos/pinmux.c
@@ -506,6 +506,9 @@ static int exynos5_pinmux_config(int peripheral, int flags)
 		 */
 		gpio_set_pull(EXYNOS5_GPIO_X07, S5P_GPIO_PULL_NONE);
 		break;
+	case PERIPH_ID_PWM0:
+		gpio_cfg_pin(EXYNOS5_GPIO_B20, S5P_GPIO_FUNC(2));
+		break;
 	default:
 		debug("%s: invalid peripheral %d", __func__, peripheral);
 		return -1;
@@ -548,6 +551,9 @@ static int exynos5420_pinmux_config(int peripheral, int flags)
 	case PERIPH_ID_I2C10:
 		exynos5420_i2c_config(peripheral);
 		break;
+	case PERIPH_ID_PWM0:
+		gpio_cfg_pin(EXYNOS5420_GPIO_B20, S5P_GPIO_FUNC(2));
+		break;
 	default:
 		debug("%s: invalid peripheral %d", __func__, peripheral);
 		return -1;
diff --git a/arch/arm/mach-exynos/power.c b/arch/arm/mach-exynos/power.c
index cd2d6618ac89b74a15aec2748aa6c6fe40f1af9a..c923460275ec70cc93d80c1ebcab97a9365fe848 100644
--- a/arch/arm/mach-exynos/power.c
+++ b/arch/arm/mach-exynos/power.c
@@ -147,7 +147,7 @@ static void exynos5_dp_phy_control(unsigned int enable)
 	writel(cfg, &power->dptx_phy_control);
 }
 
-void set_dp_phy_ctrl(unsigned int enable)
+void exynos_dp_phy_ctrl(unsigned int enable)
 {
 	if (cpu_is_exynos5())
 		exynos5_dp_phy_control(enable);
diff --git a/arch/arm/mach-exynos/soc.c b/arch/arm/mach-exynos/soc.c
index 0f116b141a327ea66c8b63675ddb7d543a48bb0a..f9c746861199eae76be4f7bd8914841c2aa151b1 100644
--- a/arch/arm/mach-exynos/soc.c
+++ b/arch/arm/mach-exynos/soc.c
@@ -11,7 +11,9 @@
 
 void reset_cpu(ulong addr)
 {
+#ifdef CONFIG_CPU_V7
 	writel(0x1, samsung_get_base_swreset());
+#endif
 }
 
 #ifndef CONFIG_SYS_DCACHE_OFF
@@ -21,3 +23,11 @@ void enable_caches(void)
 	dcache_enable();
 }
 #endif
+
+#ifdef CONFIG_ARM64
+void lowlevel_init(void)
+{
+	armv8_switch_to_el2();
+	armv8_switch_to_el1();
+}
+#endif
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c
index 1334c22ddd90f171f63540fc9b8bcf798240cb88..0eb066ce4782a5c281556c572a155d62428d8104 100644
--- a/board/samsung/common/board.c
+++ b/board/samsung/common/board.c
@@ -27,6 +27,8 @@
 #include <usb.h>
 #include <dwc3-uboot.h>
 #include <samsung/misc.h>
+#include <dm/pinctrl.h>
+#include <dm.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -97,7 +99,7 @@ int board_init(void)
 int dram_init(void)
 {
 	unsigned int i;
-	u32 addr;
+	unsigned long addr;
 
 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 		addr = CONFIG_SYS_SDRAM_BASE + (i * SDRAM_BANK_SIZE);
@@ -109,7 +111,7 @@ int dram_init(void)
 void dram_init_banksize(void)
 {
 	unsigned int i;
-	u32 addr, size;
+	unsigned long addr, size;
 
 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 		addr = CONFIG_SYS_SDRAM_BASE + (i * SDRAM_BANK_SIZE);
@@ -122,6 +124,7 @@ void dram_init_banksize(void)
 
 static int board_uart_init(void)
 {
+#ifndef CONFIG_PINCTRL_EXYNOS
 	int err, uart_id, ret = 0;
 
 	for (uart_id = PERIPH_ID_UART0; uart_id <= PERIPH_ID_UART3; uart_id++) {
@@ -133,6 +136,9 @@ static int board_uart_init(void)
 		}
 	}
 	return ret;
+#else
+	return 0;
+#endif
 }
 
 #ifdef CONFIG_BOARD_EARLY_INIT_F
@@ -152,21 +158,6 @@ int board_early_init_f(void)
 	board_i2c_init(gd->fdt_blob);
 #endif
 
-#if defined(CONFIG_EXYNOS_FB)
-	/*
-	 * board_init_f(arch/arm/lib/board.c) calls lcd_setmem() which needs
-	 * panel_info.vl_col, panel_info.vl_row and panel_info.vl_bpix,
-	 * to reserve frame-buffer memory at a very early stage. So, we need
-	 * to fill panel_info.vl_col, panel_info.vl_row and panel_info.vl_bpix
-	 * before lcd_setmem() is called.
-	 */
-	err = exynos_lcd_early_init(gd->fdt_blob);
-	if (err) {
-		debug("LCD early init failed\n");
-		return err;
-	}
-#endif
-
 	return exynos_early_init_f();
 }
 #endif
diff --git a/board/samsung/common/exynos5-dt.c b/board/samsung/common/exynos5-dt.c
index 4d9e151756b3be9555c81e539bf76f0baee2fbe7..2e3b16df45d46c2f93db02529e140d6b5fd0f62c 100644
--- a/board/samsung/common/exynos5-dt.c
+++ b/board/samsung/common/exynos5-dt.c
@@ -147,164 +147,6 @@ int board_get_revision(void)
 	return 0;
 }
 
-#ifdef CONFIG_LCD
-
-static int board_dp_bridge_init(struct udevice *dev)
-{
-	const int max_tries = 10;
-	int num_tries;
-	int ret;
-
-	debug("%s\n", __func__);
-	ret = video_bridge_attach(dev);
-	if (ret) {
-		debug("video bridge init failed: %d\n", ret);
-		return ret;
-	}
-
-	/*
-	 * We need to wait for 90ms after bringing up the bridge since there
-	 * is a phantom "high" on the HPD chip during its bootup.  The phantom
-	 * high comes within 7ms of de-asserting PD and persists for at least
-	 * 15ms.  The real high comes roughly 50ms after PD is de-asserted. The
-	 * phantom high makes it hard for us to know when the NXP chip is up.
-	 */
-	mdelay(90);
-
-	for (num_tries = 0; num_tries < max_tries; num_tries++) {
-		/* Check HPD. If it's high, or we don't have it, all is well */
-		ret = video_bridge_check_attached(dev);
-		if (!ret || ret == -ENOENT)
-			return 0;
-
-		debug("%s: eDP bridge failed to come up; try %d of %d\n",
-		      __func__, num_tries, max_tries);
-	}
-
-	/* Immediately go into bridge reset if the hp line is not high */
-	return -EIO;
-}
-
-static int board_dp_bridge_setup(const void *blob)
-{
-	const int max_tries = 2;
-	int num_tries;
-	struct udevice *dev;
-	int ret;
-
-	/* Configure I2C registers for Parade bridge */
-	ret = uclass_get_device(UCLASS_VIDEO_BRIDGE, 0, &dev);
-	if (ret) {
-		debug("video bridge init failed: %d\n", ret);
-		return ret;
-	}
-
-	if (strncmp(dev->driver->name, "parade", 6)) {
-		/* Mux HPHPD to the special hotplug detect mode */
-		exynos_pinmux_config(PERIPH_ID_DPHPD, 0);
-	}
-
-	for (num_tries = 0; num_tries < max_tries; num_tries++) {
-		ret = board_dp_bridge_init(dev);
-		if (!ret)
-			return 0;
-		if (num_tries == max_tries - 1)
-			break;
-
-		/*
-		* If we're here, the bridge chip failed to initialise.
-		* Power down the bridge in an attempt to reset.
-		*/
-		video_bridge_set_active(dev, false);
-
-		/*
-		* Arbitrarily wait 300ms here with DP_N low.  Don't know for
-		* sure how long we should wait, but we're being paranoid.
-		*/
-		mdelay(300);
-	}
-
-	return ret;
-}
-
-void exynos_cfg_lcd_gpio(void)
-{
-	/* For Backlight */
-	gpio_request(EXYNOS5_GPIO_B20, "lcd_backlight");
-	gpio_cfg_pin(EXYNOS5_GPIO_B20, S5P_GPIO_OUTPUT);
-	gpio_set_value(EXYNOS5_GPIO_B20, 1);
-}
-
-void exynos_set_dp_phy(unsigned int onoff)
-{
-	set_dp_phy_ctrl(onoff);
-}
-
-static int board_dp_set_backlight(int percent)
-{
-	struct udevice *dev;
-	int ret;
-
-	ret = uclass_get_device(UCLASS_VIDEO_BRIDGE, 0, &dev);
-	if (!ret)
-		ret = video_bridge_set_backlight(dev, percent);
-
-	return ret;
-}
-
-void exynos_backlight_on(unsigned int on)
-{
-	struct udevice *dev;
-	int ret;
-
-	debug("%s(%u)\n", __func__, on);
-	if (!on)
-		return;
-
-	ret = regulator_get_by_platname("vcd_led", &dev);
-	if (!ret)
-		ret = regulator_set_enable(dev, true);
-	if (ret)
-		debug("Failed to enable backlight: ret=%d\n", ret);
-
-	/* T5 in the LCD timing spec (defined as > 10ms) */
-	mdelay(10);
-
-	/* board_dp_backlight_pwm */
-	gpio_direction_output(EXYNOS5_GPIO_B20, 1);
-
-	/* T6 in the LCD timing spec (defined as > 10ms) */
-	mdelay(10);
-
-	/* try to set the backlight in the bridge registers */
-	ret = board_dp_set_backlight(80);
-
-	/* if we have no bridge or it does not support backlight, use a GPIO */
-	if (ret == -ENODEV || ret == -ENOSYS) {
-		gpio_request(EXYNOS5_GPIO_X30, "board_dp_backlight_en");
-		gpio_direction_output(EXYNOS5_GPIO_X30, 1);
-	}
-}
-
-void exynos_lcd_power_on(void)
-{
-	struct udevice *dev;
-	int ret;
-
-	debug("%s\n", __func__);
-	ret = regulator_get_by_platname("lcd_vdd", &dev);
-	if (!ret)
-		ret = regulator_set_enable(dev, true);
-	if (ret)
-		debug("Failed to enable LCD panel: ret=%d\n", ret);
-
-	ret = board_dp_bridge_setup(gd->fdt_blob);
-	if (ret && ret != -ENODEV)
-		printf("LCD bridge failed to enable: %d\n", ret);
-}
-
-#endif
-
 #ifdef CONFIG_USB_DWC3
 static struct dwc3_device dwc3_device_data = {
 	.maximum_speed = USB_SPEED_SUPER,
diff --git a/board/samsung/common/misc.c b/board/samsung/common/misc.c
index da0d4db1f9d4628041266e8fcec625c9890a430f..77d0a4e837f0072eae4d12707ca014ef3c8fe9bc 100644
--- a/board/samsung/common/misc.c
+++ b/board/samsung/common/misc.c
@@ -147,6 +147,7 @@ static int key_pressed(int key)
 	return value;
 }
 
+#ifdef CONFIG_LCD
 static int check_keys(void)
 {
 	int keys = 0;
@@ -235,9 +236,11 @@ static void display_board_info(void)
 
 	lcd_printf("\tDisplay BPP: %u\n", 1 << vid->vl_bpix);
 }
+#endif
 
 static int mode_leave_menu(int mode)
 {
+#ifdef CONFIG_LCD
 	char *exit_option;
 	char *exit_reset = "reset";
 	char *exit_back = "back";
@@ -301,8 +304,12 @@ static int mode_leave_menu(int mode)
 
 	lcd_clear();
 	return leave;
+#else
+	return 0;
+#endif
 }
 
+#ifdef CONFIG_LCD
 static void display_download_menu(int mode)
 {
 	char *selection[BOOT_MODE_EXIT + 1];
@@ -320,9 +327,11 @@ static void display_download_menu(int mode)
 		lcd_printf("\t%s  %s - %s\n\n", selection[i],
 			   mode_name[i][0], mode_info[i]);
 }
+#endif
 
 static void download_menu(void)
 {
+#ifdef CONFIG_LCD
 	int mode = 0;
 	int last_mode = 0;
 	int run;
@@ -393,6 +402,7 @@ static void download_menu(void)
 	}
 
 	lcd_clear();
+#endif
 }
 
 void check_boot_mode(void)
diff --git a/board/samsung/espresso7420/Kconfig b/board/samsung/espresso7420/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..62251c5126dc652434e970925405cd71140f5de3
--- /dev/null
+++ b/board/samsung/espresso7420/Kconfig
@@ -0,0 +1,16 @@
+if TARGET_ESPRESSO7420
+
+config SYS_BOARD
+	default "espresso7420"
+	help
+	  Espresso7420 is a development/evaluation board for Exynos7420 SoC.
+	  It includes multiple onboard compoments (EMMC/Codec) and various
+	  interconnects (USB/HDMI).
+
+config SYS_VENDOR
+	default "samsung"
+
+config SYS_CONFIG_NAME
+	default "espresso7420"
+
+endif
diff --git a/board/samsung/espresso7420/MAINTAINERS b/board/samsung/espresso7420/MAINTAINERS
new file mode 100644
index 0000000000000000000000000000000000000000..aaebc4c22d67c2a4e7071097f1d34c5f9f4fca3d
--- /dev/null
+++ b/board/samsung/espresso7420/MAINTAINERS
@@ -0,0 +1,5 @@
+ESPRESSO7420 Board
+M:	Thomas Abraham <thomas.ab@samsung.com>
+S:	Maintained
+F:	board/samsung/espresso7420/
+F:	include/configs/espresso7420.h
diff --git a/board/samsung/espresso7420/Makefile b/board/samsung/espresso7420/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..d514dc2a457aa3f6b8a60077cb251173bbc121ff
--- /dev/null
+++ b/board/samsung/espresso7420/Makefile
@@ -0,0 +1,10 @@
+#
+# Copyright (C) 2016 Samsung Electronics
+# Thomas Abraham <thomas.ab@samsung.com>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+ifndef CONFIG_SPL_BUILD
+obj-y	+= espresso7420.o
+endif
diff --git a/board/samsung/espresso7420/espresso7420.c b/board/samsung/espresso7420/espresso7420.c
new file mode 100644
index 0000000000000000000000000000000000000000..04a83bc07d79496bec86d3ee764448d1ead365ad
--- /dev/null
+++ b/board/samsung/espresso7420/espresso7420.c
@@ -0,0 +1,16 @@
+/*
+ * Espresso7420 board file
+ * Copyright (C) 2016 Samsung Electronics
+ * Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int exynos_init(void)
+{
+	return 0;
+}
diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c
index 54d01ec439a239b27b341014d8546074570f3ef5..66a54d436ded8182c8d6a53b8d02bca93f43980d 100644
--- a/board/samsung/trats/trats.c
+++ b/board/samsung/trats/trats.c
@@ -596,6 +596,7 @@ int mipi_power(void)
 	return 0;
 }
 
+#ifdef CONFIG_LCD
 void exynos_lcd_misc_init(vidinfo_t *vid)
 {
 #ifdef CONFIG_TIZEN
@@ -606,3 +607,4 @@ void exynos_lcd_misc_init(vidinfo_t *vid)
 	setenv("lcdinfo", "lcd=s6e8ax0");
 #endif
 }
+#endif
diff --git a/board/samsung/universal_c210/universal.c b/board/samsung/universal_c210/universal.c
index 426ae14af26db0e19da90e0a75201095d802f3b7..81e35b6f7590308c612d358249819464c002678d 100644
--- a/board/samsung/universal_c210/universal.c
+++ b/board/samsung/universal_c210/universal.c
@@ -367,6 +367,7 @@ int exynos_init(void)
 	return 0;
 }
 
+#ifdef CONFIG_LCD
 void exynos_lcd_misc_init(vidinfo_t *vid)
 {
 #ifdef CONFIG_TIZEN
@@ -379,3 +380,4 @@ void exynos_lcd_misc_init(vidinfo_t *vid)
 
 	setenv("lcdinfo", "lcd=ld9040");
 }
+#endif
diff --git a/configs/arndale_defconfig b/configs/arndale_defconfig
index 0cd529ee8889e0f2290da6b481aa31ca6115666e..a026fd6104b23bb8d4b42b0b32b85cb0e22ff793 100644
--- a/configs/arndale_defconfig
+++ b/configs/arndale_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS5=y
 CONFIG_TARGET_ARNDALE=y
 CONFIG_DM_I2C=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos5250-arndale"
diff --git a/configs/espresso7420_defconfig b/configs/espresso7420_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..0fe2759607bc36fc2483890d03995603b49c0b68
--- /dev/null
+++ b/configs/espresso7420_defconfig
@@ -0,0 +1,9 @@
+CONFIG_ARM=y
+CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS7=y
+CONFIG_TARGET_ESPRESSO7420=y
+CONFIG_DEFAULT_DEVICE_TREE="exynos7420-espresso7420"
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SYS_PROMPT="ESPRESSO7420 # "
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_SETEXPR is not set
diff --git a/configs/odroid-xu3_defconfig b/configs/odroid-xu3_defconfig
index 49cfa8c02adcfa16cbb5d61646fe1a7680e206d3..c1d0fc3f8e1c42123a538a599db8868d143ff9a5 100644
--- a/configs/odroid-xu3_defconfig
+++ b/configs/odroid-xu3_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS5=y
 CONFIG_TARGET_ODROID_XU3=y
 CONFIG_DM_I2C=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos5422-odroidxu3"
diff --git a/configs/odroid_defconfig b/configs/odroid_defconfig
index ff3b3390f66677f766985d1c3f74b5c7e12382c1..76ab144fbbb8dad74d0dcdf8e9cb7228ef8ff7e6 100644
--- a/configs/odroid_defconfig
+++ b/configs/odroid_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS4=y
 CONFIG_TARGET_ODROID=y
 CONFIG_DM_I2C=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos4412-odroid"
diff --git a/configs/origen_defconfig b/configs/origen_defconfig
index b1740dcc3f91c50ec39ddb9efac3f23a81a2db9a..6ad01af520fdd9c90244cff39fe3d111a60104c3 100644
--- a/configs/origen_defconfig
+++ b/configs/origen_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS4=y
 CONFIG_TARGET_ORIGEN=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos4210-origen"
 CONFIG_SPL=y
diff --git a/configs/peach-pi_defconfig b/configs/peach-pi_defconfig
index 3c403ba8da7146293f9b9e7816954fc1e8ae6380..313fb03e661439a67a717da43a78f455b7e652e6 100644
--- a/configs/peach-pi_defconfig
+++ b/configs/peach-pi_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS5=y
 CONFIG_TARGET_PEACH_PI=y
 CONFIG_DM_I2C=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos5800-peach-pi"
@@ -46,6 +47,8 @@ CONFIG_DM_PMIC=y
 CONFIG_PMIC_TPS65090=y
 CONFIG_DM_REGULATOR=y
 CONFIG_REGULATOR_TPS65090=y
+CONFIG_DM_PWM=y
+CONFIG_PWM_EXYNOS=y
 CONFIG_SOUND=y
 CONFIG_I2S=y
 CONFIG_I2S_SAMSUNG=y
@@ -57,6 +60,8 @@ CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
+CONFIG_DM_VIDEO=y
+CONFIG_DISPLAY=y
 CONFIG_VIDEO_BRIDGE=y
 CONFIG_VIDEO_BRIDGE_PARADE_PS862X=y
 CONFIG_TPM=y
diff --git a/configs/peach-pit_defconfig b/configs/peach-pit_defconfig
index bfa361498cbd5933b3397b10ef14d3d8668ae716..eb5558a4089b0c6f938ff9f0fc7fc124d2c17c83 100644
--- a/configs/peach-pit_defconfig
+++ b/configs/peach-pit_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS5=y
 CONFIG_TARGET_PEACH_PIT=y
 CONFIG_DM_I2C=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos5420-peach-pit"
@@ -46,6 +47,8 @@ CONFIG_DM_PMIC=y
 CONFIG_PMIC_TPS65090=y
 CONFIG_DM_REGULATOR=y
 CONFIG_REGULATOR_TPS65090=y
+CONFIG_DM_PWM=y
+CONFIG_PWM_EXYNOS=y
 CONFIG_SOUND=y
 CONFIG_I2S=y
 CONFIG_I2S_SAMSUNG=y
@@ -57,6 +60,8 @@ CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
+CONFIG_DM_VIDEO=y
+CONFIG_DISPLAY=y
 CONFIG_VIDEO_BRIDGE=y
 CONFIG_VIDEO_BRIDGE_PARADE_PS862X=y
 CONFIG_TPM=y
diff --git a/configs/s5pc210_universal_defconfig b/configs/s5pc210_universal_defconfig
index 638b72896d0fd575ac8b73564cc983b6088f6fa1..5eb7a40e903c20cad73a85fc6745118eb4dc7122 100644
--- a/configs/s5pc210_universal_defconfig
+++ b/configs/s5pc210_universal_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS4=y
 CONFIG_TARGET_S5PC210_UNIVERSAL=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos4210-universal_c210"
 CONFIG_HUSH_PARSER=y
diff --git a/configs/smdk5250_defconfig b/configs/smdk5250_defconfig
index 5d883918b1fd506edf6be4d84f23b57031d295d2..7fe410d7b3f88c3dba2c9a2d6cd1fecf8da0228e 100644
--- a/configs/smdk5250_defconfig
+++ b/configs/smdk5250_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS5=y
 CONFIG_TARGET_SMDK5250=y
 CONFIG_DM_I2C=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos5250-smdk5250"
diff --git a/configs/smdk5420_defconfig b/configs/smdk5420_defconfig
index 3bda611f767c8e4fba9b004dba3f37f0f6031f9d..43d33894c8876c5d3febb000c9cd810e75bce0e6 100644
--- a/configs/smdk5420_defconfig
+++ b/configs/smdk5420_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS5=y
 CONFIG_TARGET_SMDK5420=y
 CONFIG_DM_I2C=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos5420-smdk5420"
diff --git a/configs/smdkv310_defconfig b/configs/smdkv310_defconfig
index b8638e2ce31b57411a4826ea4b46cca281efa056..5ba6523bdb32ae5438f38cdaee3f2f603b52cd32 100644
--- a/configs/smdkv310_defconfig
+++ b/configs/smdkv310_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS4=y
 CONFIG_TARGET_SMDKV310=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos4210-smdkv310"
 CONFIG_SPL=y
diff --git a/configs/snow_defconfig b/configs/snow_defconfig
index 97133dfe680b6d89348e47088a2d8c79cf3c852c..c16c90c4533f12bdd35a4964d48310a60076c010 100644
--- a/configs/snow_defconfig
+++ b/configs/snow_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS5=y
 CONFIG_TARGET_SNOW=y
 CONFIG_DM_I2C=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos5250-snow"
@@ -51,6 +52,8 @@ CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_MAX77686=y
 CONFIG_REGULATOR_S5M8767=y
 CONFIG_REGULATOR_TPS65090=y
+CONFIG_DM_PWM=y
+CONFIG_PWM_EXYNOS=y
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART_S5P=y
 CONFIG_DEBUG_UART_BASE=0x12c30000
@@ -64,6 +67,8 @@ CONFIG_EXYNOS_SPI=y
 CONFIG_TPM_TIS_INFINEON=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_DM_VIDEO=y
+CONFIG_DISPLAY=y
 CONFIG_VIDEO_BRIDGE=y
 CONFIG_VIDEO_BRIDGE_PARADE_PS862X=y
 CONFIG_VIDEO_BRIDGE_NXP_PTN3460=y
diff --git a/configs/spring_defconfig b/configs/spring_defconfig
index b720e040d31e7f71f697c760b5e3d8610adb54be..b68cab054326698184e6d22e988843fd92e2e081 100644
--- a/configs/spring_defconfig
+++ b/configs/spring_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS5=y
 CONFIG_TARGET_SPRING=y
 CONFIG_DM_I2C=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos5250-spring"
@@ -51,6 +52,8 @@ CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_MAX77686=y
 CONFIG_REGULATOR_S5M8767=y
 CONFIG_REGULATOR_TPS65090=y
+CONFIG_DM_PWM=y
+CONFIG_PWM_EXYNOS=y
 CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART_S5P=y
 CONFIG_DEBUG_UART_BASE=0x12c30000
@@ -64,6 +67,8 @@ CONFIG_EXYNOS_SPI=y
 CONFIG_TPM_TIS_INFINEON=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_DM_VIDEO=y
+CONFIG_DISPLAY=y
 CONFIG_VIDEO_BRIDGE=y
 CONFIG_VIDEO_BRIDGE_PARADE_PS862X=y
 CONFIG_TPM=y
diff --git a/configs/trats2_defconfig b/configs/trats2_defconfig
index c2ed8c8adfae78d8c5f862225e5ac926c6bd9304..1362ffb7b881591f8ed0482245d5d692973c58f5 100644
--- a/configs/trats2_defconfig
+++ b/configs/trats2_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS4=y
 CONFIG_TARGET_TRATS2=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos4412-trats2"
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
diff --git a/configs/trats_defconfig b/configs/trats_defconfig
index 46bfc4e71ca90dd81ac56a6800c638adf3b51bc0..525bbefa141eceb7fffcef6c61c079736a582d45 100644
--- a/configs/trats_defconfig
+++ b/configs/trats_defconfig
@@ -1,5 +1,6 @@
 CONFIG_ARM=y
 CONFIG_ARCH_EXYNOS=y
+CONFIG_ARCH_EXYNOS4=y
 CONFIG_TARGET_TRATS=y
 CONFIG_DEFAULT_DEVICE_TREE="exynos4210-trats"
 CONFIG_FIT=y
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index a98b74bbc0cfe14b07b11b0ad760ea2521fff878..6eee8eb369bf5bee5d613dd76e506b83f4f99635 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -21,5 +21,6 @@ config SPL_CLK
 	  used as U-Boot proper.
 
 source "drivers/clk/uniphier/Kconfig"
+source "drivers/clk/exynos/Kconfig"
 
 endmenu
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index c51db1562b6436fcfab7df5ebd64c212112473de..81fe600188cc030cb9b585b987b5fc242a9a89c0 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o
 obj-$(CONFIG_SANDBOX) += clk_sandbox.o
 obj-$(CONFIG_MACH_PIC32) += clk_pic32.o
 obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
+obj-$(CONFIG_CLK_EXYNOS) += exynos/
diff --git a/drivers/clk/exynos/Kconfig b/drivers/clk/exynos/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..eb0efa97d15ceb6c23963d9d742dcd0317fb494e
--- /dev/null
+++ b/drivers/clk/exynos/Kconfig
@@ -0,0 +1,18 @@
+config CLK_EXYNOS
+	bool
+	select CLK
+	help
+	  This enables support for common clock driver API on Samsung
+	  Exynos SoCs.
+
+menu "Clock drivers for Exynos SoCs"
+	depends on CLK_EXYNOS
+
+config CLK_EXYNOS7420
+	bool "Clock driver for Samsung's Exynos7420 SoC"
+	default y
+	help
+	  This enables common clock driver support for platforms based
+	  on Samsung Exynos7420 SoC.
+
+endmenu
diff --git a/drivers/clk/exynos/Makefile b/drivers/clk/exynos/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1df10fe84a1ba913980cffc14195ac3f6c719345
--- /dev/null
+++ b/drivers/clk/exynos/Makefile
@@ -0,0 +1,9 @@
+#
+# Copyright (C) 2016 Samsung Electronics
+# Thomas Abraham <thomas.ab@samsung.com>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y				+= clk-pll.o
+obj-$(CONFIG_CLK_EXYNOS7420)	+= clk-exynos7420.o
diff --git a/drivers/clk/exynos/clk-exynos7420.c b/drivers/clk/exynos/clk-exynos7420.c
new file mode 100644
index 0000000000000000000000000000000000000000..bf5d0e6e6032ac563642f9d6500c830e7cd63e4c
--- /dev/null
+++ b/drivers/clk/exynos/clk-exynos7420.c
@@ -0,0 +1,236 @@
+/*
+ * Samsung Exynos7420 clock driver.
+ * Copyright (C) 2016 Samsung Electronics
+ * Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <clk.h>
+#include <asm/io.h>
+#include <dt-bindings/clock/exynos7420-clk.h>
+#include "clk-pll.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define DIVIDER(reg, shift, mask)	\
+	(((readl(reg) >> shift) & mask) + 1)
+
+/* CMU TOPC block device structure */
+struct exynos7420_clk_cmu_topc {
+	unsigned int	rsvd1[68];
+	unsigned int	bus0_pll_con[2];
+	unsigned int	rsvd2[2];
+	unsigned int	bus1_pll_con[2];
+	unsigned int	rsvd3[54];
+	unsigned int	mux_sel[6];
+	unsigned int	rsvd4[250];
+	unsigned int	div[4];
+};
+
+/* CMU TOP0 block device structure */
+struct exynos7420_clk_cmu_top0 {
+	unsigned int	rsvd0[128];
+	unsigned int	mux_sel[7];
+	unsigned int	rsvd1[261];
+	unsigned int	div_peric[5];
+};
+
+/**
+ * struct exynos7420_clk_topc_priv - private data for CMU topc clock driver.
+ *
+ * @topc: base address of the memory mapped CMU TOPC controller.
+ * @fin_freq: frequency of the Oscillator clock.
+ * @sclk_bus0_pll_a: frequency of sclk_bus0_pll_a clock.
+ * @sclk_bus1_pll_a: frequency of sclk_bus1_pll_a clock.
+ */
+struct exynos7420_clk_topc_priv {
+	struct exynos7420_clk_cmu_topc *topc;
+	unsigned long fin_freq;
+	unsigned long sclk_bus0_pll_a;
+	unsigned long sclk_bus1_pll_a;
+};
+
+/**
+ * struct exynos7420_clk_top0_priv - private data for CMU top0 clock driver.
+ *
+ * @top0: base address of the memory mapped CMU TOP0 controller.
+ * @mout_top0_bus0_pll_half: frequency of mout_top0_bus0_pll_half clock
+ * @sclk_uart2: frequency of sclk_uart2 clock.
+ */
+struct exynos7420_clk_top0_priv {
+	struct exynos7420_clk_cmu_top0 *top0;
+	unsigned long mout_top0_bus0_pll_half;
+	unsigned long sclk_uart2;
+};
+
+static ulong exynos7420_topc_get_periph_rate(struct udevice *dev, int periph)
+{
+	struct exynos7420_clk_topc_priv *priv = dev_get_priv(dev);
+
+	switch (periph) {
+	case DOUT_SCLK_BUS0_PLL:
+	case SCLK_BUS0_PLL_A:
+	case SCLK_BUS0_PLL_B:
+		return priv->sclk_bus0_pll_a;
+	case DOUT_SCLK_BUS1_PLL:
+	case SCLK_BUS1_PLL_A:
+	case SCLK_BUS1_PLL_B:
+		return priv->sclk_bus1_pll_a;
+	default:
+		return 0;
+	}
+}
+
+static struct clk_ops exynos7420_clk_topc_ops = {
+	.get_periph_rate	= exynos7420_topc_get_periph_rate,
+};
+
+static int exynos7420_clk_topc_probe(struct udevice *dev)
+{
+	struct exynos7420_clk_topc_priv *priv = dev_get_priv(dev);
+	struct exynos7420_clk_cmu_topc *topc;
+	struct udevice *clk_dev;
+	unsigned long rate;
+	fdt_addr_t base;
+	int ret;
+
+	base = dev_get_addr(dev);
+	if (base == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	topc = (struct exynos7420_clk_cmu_topc *)base;
+	priv->topc = topc;
+
+	ret = clk_get_by_index(dev, 0, &clk_dev);
+	if (ret >= 0)
+		priv->fin_freq = clk_get_rate(clk_dev);
+
+	rate = pll145x_get_rate(&topc->bus0_pll_con[0], priv->fin_freq);
+	if (readl(&topc->mux_sel[1]) & (1 << 16))
+		rate >>= 1;
+	rate /= DIVIDER(&topc->div[3], 0, 0xf);
+	priv->sclk_bus0_pll_a = rate;
+
+	rate = pll145x_get_rate(&topc->bus1_pll_con[0], priv->fin_freq) /
+			DIVIDER(&topc->div[3], 8, 0xf);
+	priv->sclk_bus1_pll_a = rate;
+
+	return 0;
+}
+
+static ulong exynos7420_top0_get_periph_rate(struct udevice *dev, int periph)
+{
+	struct exynos7420_clk_top0_priv *priv = dev_get_priv(dev);
+	struct exynos7420_clk_cmu_top0 *top0 = priv->top0;
+
+	switch (periph) {
+	case CLK_SCLK_UART2:
+		return priv->mout_top0_bus0_pll_half /
+			DIVIDER(&top0->div_peric[3], 8, 0xf);
+	default:
+		return 0;
+	}
+}
+
+static struct clk_ops exynos7420_clk_top0_ops = {
+	.get_periph_rate	= exynos7420_top0_get_periph_rate,
+};
+
+static int exynos7420_clk_top0_probe(struct udevice *dev)
+{
+	struct exynos7420_clk_top0_priv *priv;
+	struct exynos7420_clk_cmu_top0 *top0;
+	struct udevice *clk_dev;
+	fdt_addr_t base;
+	int ret;
+
+	priv = dev_get_priv(dev);
+	if (!priv)
+		return -EINVAL;
+
+	base = dev_get_addr(dev);
+	if (base == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	top0 = (struct exynos7420_clk_cmu_top0 *)base;
+	priv->top0 = top0;
+
+	ret = clk_get_by_index(dev, 1, &clk_dev);
+	if (ret >= 0) {
+		priv->mout_top0_bus0_pll_half =
+			clk_get_periph_rate(clk_dev, ret);
+		if (readl(&top0->mux_sel[1]) & (1 << 16))
+			priv->mout_top0_bus0_pll_half >>= 1;
+	}
+
+	return 0;
+}
+
+static ulong exynos7420_peric1_get_periph_rate(struct udevice *dev, int periph)
+{
+	struct udevice *clk_dev;
+	unsigned int ret;
+	unsigned long freq = 0;
+
+	switch (periph) {
+	case SCLK_UART2:
+		ret = clk_get_by_index(dev, 3, &clk_dev);
+		if (ret < 0)
+			return ret;
+		freq = clk_get_periph_rate(clk_dev, ret);
+		break;
+	}
+
+	return freq;
+}
+
+static struct clk_ops exynos7420_clk_peric1_ops = {
+	.get_periph_rate	= exynos7420_peric1_get_periph_rate,
+};
+
+static const struct udevice_id exynos7420_clk_topc_compat[] = {
+	{ .compatible = "samsung,exynos7-clock-topc" },
+	{ }
+};
+
+U_BOOT_DRIVER(exynos7420_clk_topc) = {
+	.name = "exynos7420-clock-topc",
+	.id = UCLASS_CLK,
+	.of_match = exynos7420_clk_topc_compat,
+	.probe = exynos7420_clk_topc_probe,
+	.priv_auto_alloc_size = sizeof(struct exynos7420_clk_topc_priv),
+	.ops = &exynos7420_clk_topc_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+static const struct udevice_id exynos7420_clk_top0_compat[] = {
+	{ .compatible = "samsung,exynos7-clock-top0" },
+	{ }
+};
+
+U_BOOT_DRIVER(exynos7420_clk_top0) = {
+	.name = "exynos7420-clock-top0",
+	.id = UCLASS_CLK,
+	.of_match = exynos7420_clk_top0_compat,
+	.probe = exynos7420_clk_top0_probe,
+	.priv_auto_alloc_size = sizeof(struct exynos7420_clk_top0_priv),
+	.ops = &exynos7420_clk_top0_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+static const struct udevice_id exynos7420_clk_peric1_compat[] = {
+	{ .compatible = "samsung,exynos7-clock-peric1" },
+	{ }
+};
+
+U_BOOT_DRIVER(exynos7420_clk_peric1) = {
+	.name = "exynos7420-clock-peric1",
+	.id = UCLASS_CLK,
+	.of_match = exynos7420_clk_peric1_compat,
+	.ops = &exynos7420_clk_peric1_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/clk/exynos/clk-pll.c b/drivers/clk/exynos/clk-pll.c
new file mode 100644
index 0000000000000000000000000000000000000000..27220c5911af06bf979fb114e86191a09bca7e30
--- /dev/null
+++ b/drivers/clk/exynos/clk-pll.c
@@ -0,0 +1,33 @@
+/*
+ * Exynos PLL helper functions for clock drivers.
+ * Copyright (C) 2016 Samsung Electronics
+ * Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <div64.h>
+
+#define PLL145X_MDIV_SHIFT	16
+#define PLL145X_MDIV_MASK	0x3ff
+#define PLL145X_PDIV_SHIFT	8
+#define PLL145X_PDIV_MASK	0x3f
+#define PLL145X_SDIV_SHIFT	0
+#define PLL145X_SDIV_MASK	0x7
+
+unsigned long pll145x_get_rate(unsigned int *con1, unsigned long fin_freq)
+{
+	unsigned long pll_con1 = readl(con1);
+	unsigned long mdiv, sdiv, pdiv;
+	uint64_t fvco = fin_freq;
+
+	mdiv = (pll_con1 >> PLL145X_MDIV_SHIFT) & PLL145X_MDIV_MASK;
+	pdiv = (pll_con1 >> PLL145X_PDIV_SHIFT) & PLL145X_PDIV_MASK;
+	sdiv = (pll_con1 >> PLL145X_SDIV_SHIFT) & PLL145X_SDIV_MASK;
+
+	fvco *= mdiv;
+	do_div(fvco, (pdiv << sdiv));
+	return (unsigned long)fvco;
+}
diff --git a/drivers/clk/exynos/clk-pll.h b/drivers/clk/exynos/clk-pll.h
new file mode 100644
index 0000000000000000000000000000000000000000..631d035f833bffed826268a895074271dc08f294
--- /dev/null
+++ b/drivers/clk/exynos/clk-pll.h
@@ -0,0 +1,9 @@
+/*
+ * Exynos PLL helper functions for clock drivers.
+ * Copyright (C) 2016 Samsung Electronics
+ * Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+unsigned long pll145x_get_rate(unsigned int *con1, unsigned long fin_freq);
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 567b7662d00d915e309fb029316ba52a60aa8271..1785e3b28cf5cabd962017e8bb173e27d2ec4e99 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -163,5 +163,6 @@ endif
 
 source "drivers/pinctrl/nxp/Kconfig"
 source "drivers/pinctrl/uniphier/Kconfig"
+source "drivers/pinctrl/exynos/Kconfig"
 
 endmenu
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index b99ed2f1916f338baafdc7abd252f22bcd52b976..7f946814d33f79d05a991cdbb862c3c96f374195 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_PINCTRL_SANDBOX)	+= pinctrl-sandbox.o
 
 obj-$(CONFIG_PINCTRL_UNIPHIER)	+= uniphier/
 obj-$(CONFIG_PIC32_PINCTRL)	+= pinctrl_pic32.o
+obj-$(CONFIG_PINCTRL_EXYNOS)	+= exynos/
diff --git a/drivers/pinctrl/exynos/Kconfig b/drivers/pinctrl/exynos/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..84b6aaae09c346fcc10f09faf7e96a0ca21a2601
--- /dev/null
+++ b/drivers/pinctrl/exynos/Kconfig
@@ -0,0 +1,10 @@
+config PINCTRL_EXYNOS
+	bool
+
+config PINCTRL_EXYNOS7420
+	bool "Samsung Exynos7420 pinctrl driver"
+	depends on ARCH_EXYNOS && PINCTRL_FULL
+	select PINCTRL_EXYNOS
+	help
+	  Support pin multiplexing and pin configuration control on
+	  Samsung's Exynos7420 SoC.
diff --git a/drivers/pinctrl/exynos/Makefile b/drivers/pinctrl/exynos/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..d9b941ac676f860ec51ccf9572d5f18381d2c0ea
--- /dev/null
+++ b/drivers/pinctrl/exynos/Makefile
@@ -0,0 +1,9 @@
+#
+# Copyright (C) 2016 Samsung Electronics
+# Thomas Abraham <thomas.ab@samsung.com>
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_PINCTRL_EXYNOS)		+= pinctrl-exynos.o
+obj-$(CONFIG_PINCTRL_EXYNOS7420)	+= pinctrl-exynos7420.o
diff --git a/drivers/pinctrl/exynos/pinctrl-exynos.c b/drivers/pinctrl/exynos/pinctrl-exynos.c
new file mode 100644
index 0000000000000000000000000000000000000000..a28405fc155fbbdeecc612ff8d7a5a06c499c7de
--- /dev/null
+++ b/drivers/pinctrl/exynos/pinctrl-exynos.c
@@ -0,0 +1,141 @@
+/*
+ * Exynos pinctrl driver common code.
+ * Copyright (C) 2016 Samsung Electronics
+ * Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include "pinctrl-exynos.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * exynos_pinctrl_setup_peri: setup pinctrl for a peripheral.
+ * conf: soc specific pin configuration data array
+ * num_conf: number of configurations in the conf array.
+ * base: base address of the pin controller.
+ */
+void exynos_pinctrl_setup_peri(struct exynos_pinctrl_config_data *conf,
+		unsigned int num_conf, unsigned long base)
+{
+	unsigned int idx, val;
+
+	for (idx = 0; idx < num_conf; idx++) {
+		val = readl(base + conf[idx].offset);
+		val &= ~(conf[idx].mask);
+		val |= conf[idx].value;
+		writel(val, base + conf[idx].offset);
+	}
+}
+
+/* given a pin-name, return the address of pin config registers */
+static unsigned long pin_to_bank_base(struct udevice *dev, const char *pin_name,
+						u32 *pin)
+{
+	struct exynos_pinctrl_priv *priv = dev_get_priv(dev);
+	const struct samsung_pin_ctrl *pin_ctrl = priv->pin_ctrl;
+	const struct samsung_pin_bank_data *bank_data = pin_ctrl->pin_banks;
+	u32 nr_banks = pin_ctrl->nr_banks, idx = 0;
+	char bank[10];
+
+	/*
+	 * The format of the pin name is <bank name>-<pin_number>.
+	 * Example: gpa0-4 (gpa0 is the bank name and 4 is the pin number.
+	 */
+	while (pin_name[idx] != '-') {
+		bank[idx] = pin_name[idx];
+		idx++;
+	}
+	bank[idx] = '\0';
+	*pin = pin_name[++idx] - '0';
+
+	/* lookup the pin bank data using the pin bank name */
+	for (idx = 0; idx < nr_banks; idx++)
+		if (!strcmp(bank, bank_data[idx].name))
+			break;
+
+	return priv->base + bank_data[idx].offset;
+}
+
+/**
+ * exynos_pinctrl_set_state: configure a pin state.
+ * dev: the pinctrl device to be configured.
+ * config: the state to be configured.
+ */
+int exynos_pinctrl_set_state(struct udevice *dev, struct udevice *config)
+{
+	const void *fdt = gd->fdt_blob;
+	int node = config->of_offset;
+	unsigned int count, idx, pin_num, ret;
+	unsigned int pinfunc, pinpud, pindrv;
+	unsigned long reg, value;
+	const char *name;
+
+	/*
+	 * refer to the following document for the pinctrl bindings
+	 * linux/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
+	 */
+	count = fdt_count_strings(fdt, node, "samsung,pins");
+	if (count <= 0)
+		return -EINVAL;
+
+	pinfunc = fdtdec_get_int(fdt, node, "samsung,pin-function", -1);
+	pinpud = fdtdec_get_int(fdt, node, "samsung,pin-pud", -1);
+	pindrv = fdtdec_get_int(fdt, node, "samsung,pin-drv", -1);
+
+	for (idx = 0; idx < count; idx++) {
+		ret = fdt_get_string_index(fdt, node, "samsung,pins",
+						idx, &name);
+		if (ret < 0)
+			continue;
+		reg = pin_to_bank_base(dev, name, &pin_num);
+
+		if (pinfunc != -1) {
+			value = readl(reg + PIN_CON);
+			value &= ~(0xf << (pin_num << 2));
+			value |= (pinfunc << (pin_num << 2));
+			writel(value, reg + PIN_CON);
+		}
+
+		if (pinpud != -1) {
+			value = readl(reg + PIN_PUD);
+			value &= ~(0x3 << (pin_num << 1));
+			value |= (pinpud << (pin_num << 1));
+			writel(value, reg + PIN_PUD);
+		}
+
+		if (pindrv != -1) {
+			value = readl(reg + PIN_DRV);
+			value &= ~(0x3 << (pin_num << 1));
+			value |= (pindrv << (pin_num << 1));
+			writel(value, reg + PIN_DRV);
+		}
+	}
+
+	return 0;
+}
+
+int exynos_pinctrl_probe(struct udevice *dev)
+{
+	struct exynos_pinctrl_priv *priv;
+	fdt_addr_t base;
+
+	priv = dev_get_priv(dev);
+	if (!priv)
+		return -EINVAL;
+
+	base = dev_get_addr(dev);
+	if (base == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	priv->base = base;
+	priv->pin_ctrl = (struct samsung_pin_ctrl *)dev_get_driver_data(dev) +
+				dev->req_seq;
+
+	return 0;
+}
diff --git a/drivers/pinctrl/exynos/pinctrl-exynos.h b/drivers/pinctrl/exynos/pinctrl-exynos.h
new file mode 100644
index 0000000000000000000000000000000000000000..abd582d31824900c0092fa87ccd8211b65028529
--- /dev/null
+++ b/drivers/pinctrl/exynos/pinctrl-exynos.h
@@ -0,0 +1,77 @@
+/*
+ * Exynos pinctrl driver header.
+ * Copyright (C) 2016 Samsung Electronics
+ * Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __PINCTRL_EXYNOS_H_
+#define __PINCTRL_EXYNOS__H_
+
+#define PIN_CON		0x00	/* Offset of pin function register */
+#define PIN_DAT		0x04	/* Offset of pin data register */
+#define PIN_PUD		0x08	/* Offset of pin pull up/down config register */
+#define PIN_DRV		0x0C	/* Offset of pin drive strength register */
+
+/**
+ * struct samsung_pin_bank_data: represent a controller pin-bank data.
+ * @offset: starting offset of the pin-bank registers.
+ * @nr_pins: number of pins included in this bank.
+ * @name: name to be prefixed for each pin in this pin bank.
+ */
+struct samsung_pin_bank_data {
+	u32		offset;
+	u8		nr_pins;
+	const char	*name;
+};
+
+#define EXYNOS_PIN_BANK(pins, reg, id)			\
+	{						\
+		.offset	= reg,				\
+		.nr_pins	= pins,			\
+		.name		= id			\
+	}
+
+/**
+ * struct samsung_pin_ctrl: represent a pin controller.
+ * @pin_banks: list of pin banks included in this controller.
+ * @nr_banks: number of pin banks.
+ */
+struct samsung_pin_ctrl {
+	const struct samsung_pin_bank_data *pin_banks;
+	u32 nr_banks;
+};
+
+/**
+ * struct exynos_pinctrl_priv: exynos pin controller driver private data
+ * @pin_ctrl: pin controller bank information.
+ * @base: base address of the pin controller instance.
+ * @num_banks: number of pin banks included in the pin controller.
+ */
+struct exynos_pinctrl_priv {
+	const struct samsung_pin_ctrl *pin_ctrl;
+	unsigned long base;
+	int num_banks;
+};
+
+/**
+ * struct exynos_pinctrl_config_data: configuration for a peripheral.
+ * @offset: offset of the config registers in the controller.
+ * @mask: value of the register to be masked with.
+ * @value: new value to be programmed.
+ */
+struct exynos_pinctrl_config_data {
+	const unsigned int	offset;
+	const unsigned int	mask;
+	const unsigned int	value;
+};
+
+
+void exynos_pinctrl_setup_peri(struct exynos_pinctrl_config_data *conf,
+		unsigned int num_conf, unsigned long base);
+int exynos_pinctrl_set_state(struct udevice *dev,
+		struct udevice *config);
+int exynos_pinctrl_probe(struct udevice *dev);
+
+#endif /* __PINCTRL_EXYNOS_H_ */
diff --git a/drivers/pinctrl/exynos/pinctrl-exynos7420.c b/drivers/pinctrl/exynos/pinctrl-exynos7420.c
new file mode 100644
index 0000000000000000000000000000000000000000..8ae5ce776a4452d2de965e2f234a155ae835dcfc
--- /dev/null
+++ b/drivers/pinctrl/exynos/pinctrl-exynos7420.c
@@ -0,0 +1,120 @@
+/*
+ * Exynos7420 pinctrl driver.
+ * Copyright (C) 2016 Samsung Electronics
+ * Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <dm/pinctrl.h>
+#include <dm/root.h>
+#include <fdtdec.h>
+#include <asm/arch/pinmux.h>
+#include "pinctrl-exynos.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define	GPD1_OFFSET	0xc0
+
+static struct exynos_pinctrl_config_data serial2_conf[] = {
+	{
+		.offset	= GPD1_OFFSET + PIN_CON,
+		.mask	= 0x00ff0000,
+		.value	= 0x00220000,
+	}, {
+		.offset	= GPD1_OFFSET + PIN_PUD,
+		.mask	= 0x00000f00,
+		.value	= 0x00000f00,
+	},
+};
+
+static int exynos7420_pinctrl_request(struct udevice *dev, int peripheral,
+						int flags)
+{
+	struct exynos_pinctrl_priv *priv = dev_get_priv(dev);
+	unsigned long base = priv->base;
+
+	switch (PERIPH_ID_UART2) {
+	case PERIPH_ID_UART2:
+		exynos_pinctrl_setup_peri(serial2_conf,
+					  ARRAY_SIZE(serial2_conf), base);
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static struct pinctrl_ops exynos7420_pinctrl_ops = {
+	.set_state	= exynos_pinctrl_set_state,
+	.request	= exynos7420_pinctrl_request,
+};
+
+/* pin banks of Exynos7420 pin-controller - BUS0 */
+static const struct samsung_pin_bank_data exynos7420_pin_banks0[] = {
+	EXYNOS_PIN_BANK(5, 0x000, "gpb0"),
+	EXYNOS_PIN_BANK(8, 0x020, "gpc0"),
+	EXYNOS_PIN_BANK(2, 0x040, "gpc1"),
+	EXYNOS_PIN_BANK(6, 0x060, "gpc2"),
+	EXYNOS_PIN_BANK(8, 0x080, "gpc3"),
+	EXYNOS_PIN_BANK(4, 0x0a0, "gpd0"),
+	EXYNOS_PIN_BANK(6, 0x0c0, "gpd1"),
+	EXYNOS_PIN_BANK(8, 0x0e0, "gpd2"),
+	EXYNOS_PIN_BANK(5, 0x100, "gpd4"),
+	EXYNOS_PIN_BANK(4, 0x120, "gpd5"),
+	EXYNOS_PIN_BANK(6, 0x140, "gpd6"),
+	EXYNOS_PIN_BANK(3, 0x160, "gpd7"),
+	EXYNOS_PIN_BANK(2, 0x180, "gpd8"),
+	EXYNOS_PIN_BANK(2, 0x1a0, "gpg0"),
+	EXYNOS_PIN_BANK(4, 0x1c0, "gpg3"),
+};
+
+/* pin banks of Exynos7420 pin-controller - FSYS0 */
+static const struct samsung_pin_bank_data exynos7420_pin_banks1[] = {
+	EXYNOS_PIN_BANK(7, 0x000, "gpr4"),
+};
+
+/* pin banks of Exynos7420 pin-controller - FSYS1 */
+static const struct samsung_pin_bank_data exynos7420_pin_banks2[] = {
+	EXYNOS_PIN_BANK(4, 0x000, "gpr0"),
+	EXYNOS_PIN_BANK(8, 0x020, "gpr1"),
+	EXYNOS_PIN_BANK(5, 0x040, "gpr2"),
+	EXYNOS_PIN_BANK(8, 0x060, "gpr3"),
+};
+
+const struct samsung_pin_ctrl exynos7420_pin_ctrl[] = {
+	{
+		/* pin-controller instance BUS0 data */
+		.pin_banks	= exynos7420_pin_banks0,
+		.nr_banks	= ARRAY_SIZE(exynos7420_pin_banks0),
+	}, {
+		/* pin-controller instance FSYS0 data */
+		.pin_banks	= exynos7420_pin_banks1,
+		.nr_banks	= ARRAY_SIZE(exynos7420_pin_banks1),
+	}, {
+		/* pin-controller instance FSYS1 data */
+		.pin_banks	= exynos7420_pin_banks2,
+		.nr_banks	= ARRAY_SIZE(exynos7420_pin_banks2),
+	},
+};
+
+static const struct udevice_id exynos7420_pinctrl_ids[] = {
+	{ .compatible = "samsung,exynos7420-pinctrl",
+		.data = (ulong)exynos7420_pin_ctrl },
+	{ }
+};
+
+U_BOOT_DRIVER(pinctrl_exynos7420) = {
+	.name		= "pinctrl_exynos7420",
+	.id		= UCLASS_PINCTRL,
+	.of_match	= exynos7420_pinctrl_ids,
+	.priv_auto_alloc_size = sizeof(struct exynos_pinctrl_priv),
+	.ops		= &exynos7420_pinctrl_ops,
+	.probe		= exynos_pinctrl_probe,
+	.flags		= DM_FLAG_PRE_RELOC
+};
diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c
index ccc5d309d6de25bbf5173595b0d1b78941b3f681..fd04b2645417f9eb5d5a649cc4ab90155d430525 100644
--- a/drivers/pinctrl/pinctrl-uclass.c
+++ b/drivers/pinctrl/pinctrl-uclass.c
@@ -287,5 +287,6 @@ static int pinctrl_post_bind(struct udevice *dev)
 UCLASS_DRIVER(pinctrl) = {
 	.id = UCLASS_PINCTRL,
 	.post_bind = pinctrl_post_bind,
+	.flags = DM_UC_FLAG_SEQ_ALIAS,
 	.name = "pinctrl",
 };
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 6f0d61e7ab2cc7b315d32c88d3ab14a9e0208fb2..37ea2b88eae1f8b46cac62fb3074320be719aa99 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -9,6 +9,15 @@ config DM_PWM
 	  frequency/period can be controlled along with the proportion of that
 	  time that the signal is high.
 
+config PWM_EXYNOS
+	bool "Enable support for the Exynos PWM"
+	depends on DM_PWM
+	help
+	  This PWM is found on Samsung Exynos 5250 and other Samsung SoCs. It
+	  supports a programmable period and duty cycle. A 32-bit counter is
+	  used. It provides 5 channels which can be independently
+	  programmed. Channel 4 (the last) is normally used as a timer.
+
 config PWM_ROCKCHIP
 	bool "Enable support for the Rockchip PWM"
 	depends on DM_PWM
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index fd414b1893e03fd7ac80cedb65e7804e8f104803..af39347aacf72842f1b0befca59468825c209379 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -15,4 +15,5 @@ obj-$(CONFIG_PWM_ROCKCHIP) += rk_pwm.o
 obj-$(CONFIG_PWM_IMX) += pwm-imx.o pwm-imx-util.o
 ifdef CONFIG_DM_PWM
 obj-$(CONFIG_PWM_TEGRA) += tegra_pwm.o
+obj-$(CONFIG_PWM_EXYNOS) += exynos_pwm.o
 endif
diff --git a/drivers/pwm/exynos_pwm.c b/drivers/pwm/exynos_pwm.c
new file mode 100644
index 0000000000000000000000000000000000000000..a0edafce40b5f1c3ef0436ec28acb65923d219a1
--- /dev/null
+++ b/drivers/pwm/exynos_pwm.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <pwm.h>
+#include <asm/io.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/pwm.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct exynos_pwm_priv {
+	struct s5p_timer *regs;
+};
+
+static int exynos_pwm_set_config(struct udevice *dev, uint channel,
+				uint period_ns, uint duty_ns)
+{
+	struct exynos_pwm_priv *priv = dev_get_priv(dev);
+	struct s5p_timer *regs = priv->regs;
+	unsigned int offset, prescaler;
+	uint div = 4, rate, rate_ns;
+	u32 val;
+	u32 tcnt, tcmp, tcon;
+
+	if (channel >= 5)
+		return -EINVAL;
+	debug("%s: Configure '%s' channel %u, period_ns %u, duty_ns %u\n",
+	      __func__, dev->name, channel, period_ns, duty_ns);
+
+	val = readl(&regs->tcfg0);
+	prescaler = (channel < 2 ? val : (val >> 8)) & 0xff;
+	div = (readl(&regs->tcfg1) >> MUX_DIV_SHIFT(channel)) & 0xf;
+
+	rate = get_pwm_clk() / ((prescaler + 1) * (1 << div));
+	debug("%s: pwm_clk %lu, rate %u\n", __func__, get_pwm_clk(), rate);
+
+	if (channel < 4) {
+		rate_ns = 1000000000 / rate;
+		tcnt = period_ns / rate_ns;
+		tcmp = duty_ns / rate_ns;
+		debug("%s: tcnt %u, tcmp %u\n", __func__, tcnt, tcmp);
+		offset = channel * 3;
+		writel(tcnt, &regs->tcntb0 + offset);
+		writel(tcmp, &regs->tcmpb0 + offset);
+	}
+
+	tcon = readl(&regs->tcon);
+	tcon |= TCON_UPDATE(channel);
+	if (channel < 4)
+		tcon |= TCON_AUTO_RELOAD(channel);
+	else
+		tcon |= TCON4_AUTO_RELOAD;
+	writel(tcon, &regs->tcon);
+
+	tcon &= ~TCON_UPDATE(channel);
+	writel(tcon, &regs->tcon);
+
+	return 0;
+}
+
+static int exynos_pwm_set_enable(struct udevice *dev, uint channel,
+				 bool enable)
+{
+	struct exynos_pwm_priv *priv = dev_get_priv(dev);
+	struct s5p_timer *regs = priv->regs;
+	u32 mask;
+
+	if (channel >= 4)
+		return -EINVAL;
+	debug("%s: Enable '%s' channel %u\n", __func__, dev->name, channel);
+	mask = TCON_START(channel);
+	clrsetbits_le32(&regs->tcon, mask, enable ? mask : 0);
+
+	return 0;
+}
+
+static int exynos_pwm_probe(struct udevice *dev)
+{
+	struct exynos_pwm_priv *priv = dev_get_priv(dev);
+	struct s5p_timer *regs = priv->regs;
+
+	writel(PRESCALER_0 | PRESCALER_1 << 8, &regs->tcfg0);
+
+	return 0;
+}
+
+static int exynos_pwm_ofdata_to_platdata(struct udevice *dev)
+{
+	struct exynos_pwm_priv *priv = dev_get_priv(dev);
+
+	priv->regs = (struct s5p_timer *)dev_get_addr(dev);
+
+	return 0;
+}
+
+static const struct pwm_ops exynos_pwm_ops = {
+	.set_config	= exynos_pwm_set_config,
+	.set_enable	= exynos_pwm_set_enable,
+};
+
+static const struct udevice_id exynos_channels[] = {
+	{ .compatible = "samsung,exynos4210-pwm" },
+	{ }
+};
+
+U_BOOT_DRIVER(exynos_pwm) = {
+	.name	= "exynos_pwm",
+	.id	= UCLASS_PWM,
+	.of_match = exynos_channels,
+	.ops	= &exynos_pwm_ops,
+	.probe	= exynos_pwm_probe,
+	.ofdata_to_platdata	= exynos_pwm_ofdata_to_platdata,
+	.priv_auto_alloc_size	= sizeof(struct exynos_pwm_priv),
+};
diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c
index feba467d809452447f07bd2973621d4cb945baa0..cb55c5ab7196a38b783b1ff9934ee22999cceb2b 100644
--- a/drivers/serial/serial_s5p.c
+++ b/drivers/serial/serial_s5p.c
@@ -17,6 +17,7 @@
 #include <asm/arch/clk.h>
 #include <asm/arch/uart.h>
 #include <serial.h>
+#include <clk.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -90,7 +91,19 @@ int s5p_serial_setbrg(struct udevice *dev, int baudrate)
 {
 	struct s5p_serial_platdata *plat = dev->platdata;
 	struct s5p_uart *const uart = plat->reg;
-	u32 uclk = get_uart_clk(plat->port_id);
+	u32 uclk;
+
+#ifdef CONFIG_CLK_EXYNOS
+	struct udevice *clk_dev;
+	u32 ret;
+
+	ret = clk_get_by_index(dev, 1, &clk_dev);
+	if (ret < 0)
+		return ret;
+	uclk = clk_get_periph_rate(clk_dev, ret);
+#else
+	uclk = get_uart_clk(plat->port_id);
+#endif
 
 	s5p_serial_baud(uart, uclk, baudrate);
 
@@ -174,8 +187,8 @@ static int s5p_serial_ofdata_to_platdata(struct udevice *dev)
 		return -EINVAL;
 
 	plat->reg = (struct s5p_uart *)addr;
-	plat->port_id = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "id", -1);
-
+	plat->port_id = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+					"id", dev->seq);
 	return 0;
 }
 
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 2fd0891e5dde9037444293a23d2e82481f17b128..3f045fe5781298d02007ab9f7698ed316c3c4bf7 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -25,11 +25,6 @@ obj-$(CONFIG_ATI_RADEON_FB) += ati_radeon_fb.o videomodes.o
 obj-$(CONFIG_ATMEL_HLCD) += atmel_hlcdfb.o
 obj-$(CONFIG_ATMEL_LCD) += atmel_lcdfb.o
 obj-$(CONFIG_CFB_CONSOLE) += cfb_console.o
-obj-$(CONFIG_EXYNOS_DP) += exynos_dp.o exynos_dp_lowlevel.o
-obj-$(CONFIG_EXYNOS_FB) += exynos_fb.o exynos_fimd.o
-obj-$(CONFIG_EXYNOS_MIPI_DSIM) += exynos_mipi_dsi.o exynos_mipi_dsi_common.o \
-				exynos_mipi_dsi_lowlevel.o
-obj-$(CONFIG_EXYNOS_PWM_BL) += exynos_pwm_bl.o
 obj-$(CONFIG_FSL_DIU_FB) += fsl_diu_fb.o videomodes.o
 obj-$(CONFIG_FSL_DCU_FB) += fsl_dcu_fb.o videomodes.o
 obj-$(CONFIG_L5F31188) += l5f31188.o
@@ -68,6 +63,7 @@ obj-$(CONFIG_LG4573) += lg4573.o
 obj-$(CONFIG_AM335X_LCD) += am335x-fb.o
 
 obj-${CONFIG_VIDEO_TEGRA124} += tegra124/
+obj-${CONFIG_EXYNOS_FB} += exynos/
 obj-${CONFIG_VIDEO_ROCKCHIP} += rockchip/
 
 obj-y += bridge/
diff --git a/drivers/video/exynos/Makefile b/drivers/video/exynos/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..001a80fa0419f0d7886d2d166ea7ba6a9d51251c
--- /dev/null
+++ b/drivers/video/exynos/Makefile
@@ -0,0 +1,12 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_EXYNOS_DP) += exynos_dp.o exynos_dp_lowlevel.o
+obj-$(CONFIG_EXYNOS_FB) += exynos_fb.o
+obj-$(CONFIG_EXYNOS_MIPI_DSIM) += exynos_mipi_dsi.o exynos_mipi_dsi_common.o \
+				exynos_mipi_dsi_lowlevel.o
+obj-$(CONFIG_EXYNOS_PWM_BL) += exynos_pwm_bl.o
diff --git a/drivers/video/exynos_dp.c b/drivers/video/exynos/exynos_dp.c
similarity index 50%
rename from drivers/video/exynos_dp.c
rename to drivers/video/exynos/exynos_dp.c
index 0d5d090d0ee79db5c3e5d26bc79d760a3f071eff..fc39f2c5620bca1cd00265ca837b895733b2e417 100644
--- a/drivers/video/exynos_dp.c
+++ b/drivers/video/exynos/exynos_dp.c
@@ -7,27 +7,26 @@
  */
 
 #include <config.h>
+#include <dm.h>
 #include <common.h>
+#include <display.h>
+#include <fdtdec.h>
+#include <libfdt.h>
 #include <malloc.h>
+#include <video_bridge.h>
 #include <linux/compat.h>
 #include <linux/err.h>
 #include <asm/arch/clk.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/dp_info.h>
 #include <asm/arch/dp.h>
-#include <fdtdec.h>
-#include <libfdt.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/power.h>
 
 #include "exynos_dp_lowlevel.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
-void __exynos_set_dp_phy(unsigned int onoff)
-{
-}
-void exynos_set_dp_phy(unsigned int onoff)
-	__attribute__((weak, alias("__exynos_set_dp_phy")));
-
 static void exynos_dp_disp_info(struct edp_disp_info *disp_info)
 {
 	disp_info->h_total = disp_info->h_res + disp_info->h_sync_width +
@@ -38,20 +37,20 @@ static void exynos_dp_disp_info(struct edp_disp_info *disp_info)
 	return;
 }
 
-static int exynos_dp_init_dp(void)
+static int exynos_dp_init_dp(struct exynos_dp *regs)
 {
 	int ret;
-	exynos_dp_reset();
+	exynos_dp_reset(regs);
 
 	/* SW defined function Normal operation */
-	exynos_dp_enable_sw_func(DP_ENABLE);
+	exynos_dp_enable_sw_func(regs, DP_ENABLE);
 
-	ret = exynos_dp_init_analog_func();
+	ret = exynos_dp_init_analog_func(regs);
 	if (ret != EXYNOS_DP_SUCCESS)
 		return ret;
 
-	exynos_dp_init_hpd();
-	exynos_dp_init_aux();
+	exynos_dp_init_hpd(regs);
+	exynos_dp_init_aux(regs);
 
 	return ret;
 }
@@ -67,7 +66,7 @@ static unsigned char exynos_dp_calc_edid_check_sum(unsigned char *edid_data)
 	return sum;
 }
 
-static unsigned int exynos_dp_read_edid(void)
+static unsigned int exynos_dp_read_edid(struct exynos_dp *regs)
 {
 	unsigned char edid[EDID_BLOCK_LENGTH * 2];
 	unsigned int extend_block = 0;
@@ -82,14 +81,15 @@ static unsigned int exynos_dp_read_edid(void)
 	 */
 
 	/* Read Extension Flag, Number of 128-byte EDID extension blocks */
-	exynos_dp_read_byte_from_i2c(I2C_EDID_DEVICE_ADDR, EDID_EXTENSION_FLAG,
-			&extend_block);
+	exynos_dp_read_byte_from_i2c(regs, I2C_EDID_DEVICE_ADDR,
+				     EDID_EXTENSION_FLAG, &extend_block);
 
 	if (extend_block > 0) {
 		printf("DP EDID data includes a single extension!\n");
 
 		/* Read EDID data */
-		retval = exynos_dp_read_bytes_from_i2c(I2C_EDID_DEVICE_ADDR,
+		retval = exynos_dp_read_bytes_from_i2c(regs,
+						I2C_EDID_DEVICE_ADDR,
 						EDID_HEADER_PATTERN,
 						EDID_BLOCK_LENGTH,
 						&edid[EDID_HEADER_PATTERN]);
@@ -104,7 +104,8 @@ static unsigned int exynos_dp_read_edid(void)
 		}
 
 		/* Read additional EDID data */
-		retval = exynos_dp_read_bytes_from_i2c(I2C_EDID_DEVICE_ADDR,
+		retval = exynos_dp_read_bytes_from_i2c(regs,
+				I2C_EDID_DEVICE_ADDR,
 				EDID_BLOCK_LENGTH,
 				EDID_BLOCK_LENGTH,
 				&edid[EDID_BLOCK_LENGTH]);
@@ -118,19 +119,22 @@ static unsigned int exynos_dp_read_edid(void)
 			return -1;
 		}
 
-		exynos_dp_read_byte_from_dpcd(DPCD_TEST_REQUEST,
-					&test_vector);
+		exynos_dp_read_byte_from_dpcd(regs, DPCD_TEST_REQUEST,
+					      &test_vector);
 		if (test_vector & DPCD_TEST_EDID_READ) {
-			exynos_dp_write_byte_to_dpcd(DPCD_TEST_EDID_CHECKSUM,
+			exynos_dp_write_byte_to_dpcd(regs,
+				DPCD_TEST_EDID_CHECKSUM,
 				edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]);
-			exynos_dp_write_byte_to_dpcd(DPCD_TEST_RESPONSE,
+			exynos_dp_write_byte_to_dpcd(regs,
+				DPCD_TEST_RESPONSE,
 				DPCD_TEST_EDID_CHECKSUM_WRITE);
 		}
 	} else {
 		debug("DP EDID data does not include any extensions.\n");
 
 		/* Read EDID data */
-		retval = exynos_dp_read_bytes_from_i2c(I2C_EDID_DEVICE_ADDR,
+		retval = exynos_dp_read_bytes_from_i2c(regs,
+				I2C_EDID_DEVICE_ADDR,
 				EDID_HEADER_PATTERN,
 				EDID_BLOCK_LENGTH,
 				&edid[EDID_HEADER_PATTERN]);
@@ -145,12 +149,13 @@ static unsigned int exynos_dp_read_edid(void)
 			return -1;
 		}
 
-		exynos_dp_read_byte_from_dpcd(DPCD_TEST_REQUEST,
+		exynos_dp_read_byte_from_dpcd(regs, DPCD_TEST_REQUEST,
 			&test_vector);
 		if (test_vector & DPCD_TEST_EDID_READ) {
-			exynos_dp_write_byte_to_dpcd(DPCD_TEST_EDID_CHECKSUM,
-				edid[EDID_CHECKSUM]);
-			exynos_dp_write_byte_to_dpcd(DPCD_TEST_RESPONSE,
+			exynos_dp_write_byte_to_dpcd(regs,
+				DPCD_TEST_EDID_CHECKSUM, edid[EDID_CHECKSUM]);
+			exynos_dp_write_byte_to_dpcd(regs,
+				DPCD_TEST_RESPONSE,
 				DPCD_TEST_EDID_CHECKSUM_WRITE);
 		}
 	}
@@ -160,7 +165,8 @@ static unsigned int exynos_dp_read_edid(void)
 	return 0;
 }
 
-static unsigned int exynos_dp_handle_edid(struct edp_device_info *edp_info)
+static unsigned int exynos_dp_handle_edid(struct exynos_dp *regs,
+					  struct exynos_dp_priv *priv)
 {
 	unsigned char buf[12];
 	unsigned int ret;
@@ -178,8 +184,8 @@ static unsigned int exynos_dp_handle_edid(struct edp_device_info *edp_info)
 	retry_cnt = 5;
 	while (retry_cnt) {
 		/* Read DPCD 0x0000-0x000b */
-		ret = exynos_dp_read_bytes_from_dpcd(DPCD_DPCD_REV, 12,
-				buf);
+		ret = exynos_dp_read_bytes_from_dpcd(regs, DPCD_DPCD_REV, 12,
+						     buf);
 		if (ret != EXYNOS_DP_SUCCESS) {
 			if (retry_cnt == 0) {
 				printf("DP read_byte_from_dpcd() failed\n");
@@ -193,7 +199,7 @@ static unsigned int exynos_dp_handle_edid(struct edp_device_info *edp_info)
 	/* */
 	temp = buf[DPCD_DPCD_REV];
 	if (temp == DP_DPCD_REV_10 || temp == DP_DPCD_REV_11)
-		edp_info->dpcd_rev = temp;
+		priv->dpcd_rev = temp;
 	else {
 		printf("DP Wrong DPCD Rev : %x\n", temp);
 		return -ENODEV;
@@ -201,33 +207,33 @@ static unsigned int exynos_dp_handle_edid(struct edp_device_info *edp_info)
 
 	temp = buf[DPCD_MAX_LINK_RATE];
 	if (temp == DP_LANE_BW_1_62 || temp == DP_LANE_BW_2_70)
-		edp_info->lane_bw = temp;
+		priv->lane_bw = temp;
 	else {
 		printf("DP Wrong MAX LINK RATE : %x\n", temp);
 		return -EINVAL;
 	}
 
 	/* Refer VESA Display Port Standard Ver1.1a Page 120 */
-	if (edp_info->dpcd_rev == DP_DPCD_REV_11) {
+	if (priv->dpcd_rev == DP_DPCD_REV_11) {
 		temp = buf[DPCD_MAX_LANE_COUNT] & 0x1f;
 		if (buf[DPCD_MAX_LANE_COUNT] & 0x80)
-			edp_info->dpcd_efc = 1;
+			priv->dpcd_efc = 1;
 		else
-			edp_info->dpcd_efc = 0;
+			priv->dpcd_efc = 0;
 	} else {
 		temp = buf[DPCD_MAX_LANE_COUNT];
-		edp_info->dpcd_efc = 0;
+		priv->dpcd_efc = 0;
 	}
 
 	if (temp == DP_LANE_CNT_1 || temp == DP_LANE_CNT_2 ||
 			temp == DP_LANE_CNT_4) {
-		edp_info->lane_cnt = temp;
+		priv->lane_cnt = temp;
 	} else {
 		printf("DP Wrong MAX LANE COUNT : %x\n", temp);
 		return -EINVAL;
 	}
 
-	ret = exynos_dp_read_edid();
+	ret = exynos_dp_read_edid(regs);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("DP exynos_dp_read_edid() failed\n");
 		return -EINVAL;
@@ -236,60 +242,60 @@ static unsigned int exynos_dp_handle_edid(struct edp_device_info *edp_info)
 	return ret;
 }
 
-static void exynos_dp_init_training(void)
+static void exynos_dp_init_training(struct exynos_dp *regs)
 {
 	/*
 	 * MACRO_RST must be applied after the PLL_LOCK to avoid
 	 * the DP inter pair skew issue for at least 10 us
 	 */
-	exynos_dp_reset_macro();
+	exynos_dp_reset_macro(regs);
 
 	/* All DP analog module power up */
-	exynos_dp_set_analog_power_down(POWER_ALL, 0);
+	exynos_dp_set_analog_power_down(regs, POWER_ALL, 0);
 }
 
-static unsigned int exynos_dp_link_start(struct edp_device_info *edp_info)
+static unsigned int exynos_dp_link_start(struct exynos_dp *regs,
+					 struct exynos_dp_priv *priv)
 {
 	unsigned char buf[5];
 	unsigned int ret = 0;
 
 	debug("DP: %s was called\n", __func__);
 
-	edp_info->lt_info.lt_status = DP_LT_CR;
-	edp_info->lt_info.ep_loop = 0;
-	edp_info->lt_info.cr_loop[0] = 0;
-	edp_info->lt_info.cr_loop[1] = 0;
-	edp_info->lt_info.cr_loop[2] = 0;
-	edp_info->lt_info.cr_loop[3] = 0;
+	priv->lt_info.lt_status = DP_LT_CR;
+	priv->lt_info.ep_loop = 0;
+	priv->lt_info.cr_loop[0] = 0;
+	priv->lt_info.cr_loop[1] = 0;
+	priv->lt_info.cr_loop[2] = 0;
+	priv->lt_info.cr_loop[3] = 0;
 
 		/* Set sink to D0 (Sink Not Ready) mode. */
-		ret = exynos_dp_write_byte_to_dpcd(DPCD_SINK_POWER_STATE,
-				DPCD_SET_POWER_STATE_D0);
+	ret = exynos_dp_write_byte_to_dpcd(regs, DPCD_SINK_POWER_STATE,
+					   DPCD_SET_POWER_STATE_D0);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("DP write_dpcd_byte failed\n");
 		return ret;
 	}
 
 	/* Set link rate and count as you want to establish */
-	exynos_dp_set_link_bandwidth(edp_info->lane_bw);
-	exynos_dp_set_lane_count(edp_info->lane_cnt);
+	exynos_dp_set_link_bandwidth(regs, priv->lane_bw);
+	exynos_dp_set_lane_count(regs, priv->lane_cnt);
 
 	/* Setup RX configuration */
-	buf[0] = edp_info->lane_bw;
-	buf[1] = edp_info->lane_cnt;
+	buf[0] = priv->lane_bw;
+	buf[1] = priv->lane_cnt;
 
-	ret = exynos_dp_write_bytes_to_dpcd(DPCD_LINK_BW_SET, 2,
-			buf);
+	ret = exynos_dp_write_bytes_to_dpcd(regs, DPCD_LINK_BW_SET, 2, buf);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("DP write_dpcd_byte failed\n");
 		return ret;
 	}
 
-	exynos_dp_set_lane_pre_emphasis(PRE_EMPHASIS_LEVEL_0,
-			edp_info->lane_cnt);
+	exynos_dp_set_lane_pre_emphasis(regs, PRE_EMPHASIS_LEVEL_0,
+			priv->lane_cnt);
 
 	/* Set training pattern 1 */
-	exynos_dp_set_training_pattern(TRAINING_PTN1);
+	exynos_dp_set_training_pattern(regs, TRAINING_PTN1);
 
 	/* Set RX training pattern */
 	buf[0] = DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_1;
@@ -303,8 +309,8 @@ static unsigned int exynos_dp_link_start(struct edp_device_info *edp_info)
 	buf[4] = DPCD_PRE_EMPHASIS_SET_PATTERN_2_LEVEL_0 |
 		DPCD_VOLTAGE_SWING_SET_PATTERN_1_LEVEL_0;
 
-	ret = exynos_dp_write_bytes_to_dpcd(DPCD_TRAINING_PATTERN_SET,
-			5, buf);
+	ret = exynos_dp_write_bytes_to_dpcd(regs, DPCD_TRAINING_PATTERN_SET,
+					    5, buf);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("DP write_dpcd_byte failed\n");
 		return ret;
@@ -313,14 +319,14 @@ static unsigned int exynos_dp_link_start(struct edp_device_info *edp_info)
 	return ret;
 }
 
-static unsigned int exynos_dp_training_pattern_dis(void)
+static unsigned int exynos_dp_training_pattern_dis(struct exynos_dp *regs)
 {
 	unsigned int ret = EXYNOS_DP_SUCCESS;
 
-	exynos_dp_set_training_pattern(DP_NONE);
+	exynos_dp_set_training_pattern(regs, DP_NONE);
 
-	ret = exynos_dp_write_byte_to_dpcd(DPCD_TRAINING_PATTERN_SET,
-			DPCD_TRAINING_PATTERN_DISABLED);
+	ret = exynos_dp_write_byte_to_dpcd(regs, DPCD_TRAINING_PATTERN_SET,
+					   DPCD_TRAINING_PATTERN_DISABLED);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("DP request_link_training_req failed\n");
 		return -EAGAIN;
@@ -329,13 +335,14 @@ static unsigned int exynos_dp_training_pattern_dis(void)
 	return ret;
 }
 
-static unsigned int exynos_dp_enable_rx_to_enhanced_mode(unsigned char enable)
+static unsigned int exynos_dp_enable_rx_to_enhanced_mode(
+		struct exynos_dp *regs, unsigned char enable)
 {
 	unsigned char data;
 	unsigned int ret = EXYNOS_DP_SUCCESS;
 
-	ret = exynos_dp_read_byte_from_dpcd(DPCD_LANE_COUNT_SET,
-			&data);
+	ret = exynos_dp_read_byte_from_dpcd(regs, DPCD_LANE_COUNT_SET,
+					    &data);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("DP read_from_dpcd failed\n");
 		return -EAGAIN;
@@ -346,8 +353,7 @@ static unsigned int exynos_dp_enable_rx_to_enhanced_mode(unsigned char enable)
 	else
 		data = DPCD_LN_COUNT_SET(data);
 
-	ret = exynos_dp_write_byte_to_dpcd(DPCD_LANE_COUNT_SET,
-			data);
+	ret = exynos_dp_write_byte_to_dpcd(regs, DPCD_LANE_COUNT_SET, data);
 	if (ret != EXYNOS_DP_SUCCESS) {
 			printf("DP write_to_dpcd failed\n");
 			return -EAGAIN;
@@ -357,23 +363,25 @@ static unsigned int exynos_dp_enable_rx_to_enhanced_mode(unsigned char enable)
 	return ret;
 }
 
-static unsigned int exynos_dp_set_enhanced_mode(unsigned char enhance_mode)
+static unsigned int exynos_dp_set_enhanced_mode(struct exynos_dp *regs,
+						unsigned char enhance_mode)
 {
 	unsigned int ret = EXYNOS_DP_SUCCESS;
 
-	ret = exynos_dp_enable_rx_to_enhanced_mode(enhance_mode);
+	ret = exynos_dp_enable_rx_to_enhanced_mode(regs, enhance_mode);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("DP rx_enhance_mode failed\n");
 		return -EAGAIN;
 	}
 
-	exynos_dp_enable_enhanced_mode(enhance_mode);
+	exynos_dp_enable_enhanced_mode(regs, enhance_mode);
 
 	return ret;
 }
 
-static int exynos_dp_read_dpcd_lane_stat(struct edp_device_info *edp_info,
-		unsigned char *status)
+static int exynos_dp_read_dpcd_lane_stat(struct exynos_dp *regs,
+					 struct exynos_dp_priv *priv,
+					 unsigned char *status)
 {
 	unsigned int ret, i;
 	unsigned char buf[2];
@@ -385,13 +393,14 @@ static int exynos_dp_read_dpcd_lane_stat(struct edp_device_info *edp_info,
 	shift_val[2] = 0;
 	shift_val[3] = 4;
 
-	ret = exynos_dp_read_bytes_from_dpcd(DPCD_LANE0_1_STATUS, 2, buf);
+	ret = exynos_dp_read_bytes_from_dpcd(regs, DPCD_LANE0_1_STATUS, 2,
+					     buf);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("DP read lane status failed\n");
 		return ret;
 	}
 
-	for (i = 0; i < edp_info->lane_cnt; i++) {
+	for (i = 0; i < priv->lane_cnt; i++) {
 		lane_stat[i] = (buf[(i / 2)] >> shift_val[i]) & 0x0f;
 		if (lane_stat[0] != lane_stat[i]) {
 			printf("Wrong lane status\n");
@@ -404,8 +413,8 @@ static int exynos_dp_read_dpcd_lane_stat(struct edp_device_info *edp_info,
 	return ret;
 }
 
-static unsigned int exynos_dp_read_dpcd_adj_req(unsigned char lane_num,
-		unsigned char *sw, unsigned char *em)
+static unsigned int exynos_dp_read_dpcd_adj_req(struct exynos_dp *regs,
+		unsigned char lane_num, unsigned char *sw, unsigned char *em)
 {
 	unsigned int ret = EXYNOS_DP_SUCCESS;
 	unsigned char buf;
@@ -415,7 +424,7 @@ static unsigned int exynos_dp_read_dpcd_adj_req(unsigned char lane_num,
 	/* lane_num value is used as array index, so this range 0 ~ 3 */
 	dpcd_addr = DPCD_ADJUST_REQUEST_LANE0_1 + (lane_num / 2);
 
-	ret = exynos_dp_read_byte_from_dpcd(dpcd_addr, &buf);
+	ret = exynos_dp_read_byte_from_dpcd(regs, dpcd_addr, &buf);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("DP read adjust request failed\n");
 		return -EAGAIN;
@@ -427,51 +436,53 @@ static unsigned int exynos_dp_read_dpcd_adj_req(unsigned char lane_num,
 	return ret;
 }
 
-static int exynos_dp_equalizer_err_link(struct edp_device_info *edp_info)
+static int exynos_dp_equalizer_err_link(struct exynos_dp *regs,
+					struct exynos_dp_priv *priv)
 {
 	int ret;
 
-	ret = exynos_dp_training_pattern_dis();
+	ret = exynos_dp_training_pattern_dis(regs);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("DP training_pattern_disable() failed\n");
-		edp_info->lt_info.lt_status = DP_LT_FAIL;
+		priv->lt_info.lt_status = DP_LT_FAIL;
 	}
 
-	ret = exynos_dp_set_enhanced_mode(edp_info->dpcd_efc);
+	ret = exynos_dp_set_enhanced_mode(regs, priv->dpcd_efc);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("DP set_enhanced_mode() failed\n");
-		edp_info->lt_info.lt_status = DP_LT_FAIL;
+		priv->lt_info.lt_status = DP_LT_FAIL;
 	}
 
 	return ret;
 }
 
-static int exynos_dp_reduce_link_rate(struct edp_device_info *edp_info)
+static int exynos_dp_reduce_link_rate(struct exynos_dp *regs,
+				      struct exynos_dp_priv *priv)
 {
 	int ret;
 
-	if (edp_info->lane_bw == DP_LANE_BW_2_70) {
-		edp_info->lane_bw = DP_LANE_BW_1_62;
+	if (priv->lane_bw == DP_LANE_BW_2_70) {
+		priv->lane_bw = DP_LANE_BW_1_62;
 		printf("DP Change lane bw to 1.62Gbps\n");
-		edp_info->lt_info.lt_status = DP_LT_START;
+		priv->lt_info.lt_status = DP_LT_START;
 		ret = EXYNOS_DP_SUCCESS;
 	} else {
-		ret = exynos_dp_training_pattern_dis();
+		ret = exynos_dp_training_pattern_dis(regs);
 		if (ret != EXYNOS_DP_SUCCESS)
 			printf("DP training_patter_disable() failed\n");
 
-		ret = exynos_dp_set_enhanced_mode(edp_info->dpcd_efc);
+		ret = exynos_dp_set_enhanced_mode(regs, priv->dpcd_efc);
 		if (ret != EXYNOS_DP_SUCCESS)
 			printf("DP set_enhanced_mode() failed\n");
 
-		edp_info->lt_info.lt_status = DP_LT_FAIL;
+		priv->lt_info.lt_status = DP_LT_FAIL;
 	}
 
 	return ret;
 }
 
-static unsigned int exynos_dp_process_clock_recovery(struct edp_device_info
-							*edp_info)
+static unsigned int exynos_dp_process_clock_recovery(struct exynos_dp *regs,
+					struct exynos_dp_priv *priv)
 {
 	unsigned int ret = EXYNOS_DP_SUCCESS;
 	unsigned char lane_stat;
@@ -484,22 +495,22 @@ static unsigned int exynos_dp_process_clock_recovery(struct edp_device_info
 	debug("DP: %s was called\n", __func__);
 	mdelay(1);
 
-	ret = exynos_dp_read_dpcd_lane_stat(edp_info, &lane_stat);
+	ret = exynos_dp_read_dpcd_lane_stat(regs, priv, &lane_stat);
 	if (ret != EXYNOS_DP_SUCCESS) {
 			printf("DP read lane status failed\n");
-			edp_info->lt_info.lt_status = DP_LT_FAIL;
+			priv->lt_info.lt_status = DP_LT_FAIL;
 			return ret;
 	}
 
 	if (lane_stat & DP_LANE_STAT_CR_DONE) {
 		debug("DP clock Recovery training succeed\n");
-		exynos_dp_set_training_pattern(TRAINING_PTN2);
+		exynos_dp_set_training_pattern(regs, TRAINING_PTN2);
 
-		for (i = 0; i < edp_info->lane_cnt; i++) {
-			ret = exynos_dp_read_dpcd_adj_req(i, &adj_req_sw,
-					&adj_req_em);
+		for (i = 0; i < priv->lane_cnt; i++) {
+			ret = exynos_dp_read_dpcd_adj_req(regs, i,
+						&adj_req_sw, &adj_req_em);
 			if (ret != EXYNOS_DP_SUCCESS) {
-				edp_info->lt_info.lt_status = DP_LT_FAIL;
+				priv->lt_info.lt_status = DP_LT_FAIL;
 				return ret;
 			}
 
@@ -511,7 +522,8 @@ static unsigned int exynos_dp_process_clock_recovery(struct edp_device_info
 				lt_ctl_val[i] |= MAX_DRIVE_CURRENT_REACH_3 |
 					MAX_PRE_EMPHASIS_REACH_3;
 			}
-			exynos_dp_set_lanex_pre_emphasis(lt_ctl_val[i], i);
+			exynos_dp_set_lanex_pre_emphasis(regs,
+							 lt_ctl_val[i], i);
 		}
 
 		buf[0] =  DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_2;
@@ -520,37 +532,39 @@ static unsigned int exynos_dp_process_clock_recovery(struct edp_device_info
 		buf[3] = lt_ctl_val[2];
 		buf[4] = lt_ctl_val[3];
 
-		ret = exynos_dp_write_bytes_to_dpcd(
+		ret = exynos_dp_write_bytes_to_dpcd(regs,
 				DPCD_TRAINING_PATTERN_SET, 5, buf);
 		if (ret != EXYNOS_DP_SUCCESS) {
 			printf("DP write training pattern1 failed\n");
-			edp_info->lt_info.lt_status = DP_LT_FAIL;
+			priv->lt_info.lt_status = DP_LT_FAIL;
 			return ret;
 		} else
-			edp_info->lt_info.lt_status = DP_LT_ET;
+			priv->lt_info.lt_status = DP_LT_ET;
 	} else {
-		for (i = 0; i < edp_info->lane_cnt; i++) {
-			lt_ctl_val[i] = exynos_dp_get_lanex_pre_emphasis(i);
-				ret = exynos_dp_read_dpcd_adj_req(i,
+		for (i = 0; i < priv->lane_cnt; i++) {
+			lt_ctl_val[i] = exynos_dp_get_lanex_pre_emphasis(
+						regs, i);
+				ret = exynos_dp_read_dpcd_adj_req(regs, i,
 						&adj_req_sw, &adj_req_em);
 			if (ret != EXYNOS_DP_SUCCESS) {
 				printf("DP read adj req failed\n");
-				edp_info->lt_info.lt_status = DP_LT_FAIL;
+				priv->lt_info.lt_status = DP_LT_FAIL;
 				return ret;
 			}
 
 			if ((adj_req_sw == VOLTAGE_LEVEL_3) ||
 					(adj_req_em == PRE_EMPHASIS_LEVEL_3))
-				ret = exynos_dp_reduce_link_rate(edp_info);
+				ret = exynos_dp_reduce_link_rate(regs,
+								 priv);
 
 			if ((DRIVE_CURRENT_SET_0_GET(lt_ctl_val[i]) ==
 						adj_req_sw) &&
 				(PRE_EMPHASIS_SET_0_GET(lt_ctl_val[i]) ==
 						adj_req_em)) {
-				edp_info->lt_info.cr_loop[i]++;
-				if (edp_info->lt_info.cr_loop[i] == MAX_CR_LOOP)
+				priv->lt_info.cr_loop[i]++;
+				if (priv->lt_info.cr_loop[i] == MAX_CR_LOOP)
 					ret = exynos_dp_reduce_link_rate(
-							edp_info);
+							regs, priv);
 			}
 
 			lt_ctl_val[i] = 0;
@@ -561,14 +575,15 @@ static unsigned int exynos_dp_process_clock_recovery(struct edp_device_info
 				lt_ctl_val[i] |= MAX_DRIVE_CURRENT_REACH_3 |
 					MAX_PRE_EMPHASIS_REACH_3;
 			}
-			exynos_dp_set_lanex_pre_emphasis(lt_ctl_val[i], i);
+			exynos_dp_set_lanex_pre_emphasis(regs,
+							 lt_ctl_val[i], i);
 		}
 
-		ret = exynos_dp_write_bytes_to_dpcd(
+		ret = exynos_dp_write_bytes_to_dpcd(regs,
 				DPCD_TRAINING_LANE0_SET, 4, lt_ctl_val);
 		if (ret != EXYNOS_DP_SUCCESS) {
 			printf("DP write training pattern2 failed\n");
-			edp_info->lt_info.lt_status = DP_LT_FAIL;
+			priv->lt_info.lt_status = DP_LT_FAIL;
 			return ret;
 		}
 	}
@@ -576,8 +591,8 @@ static unsigned int exynos_dp_process_clock_recovery(struct edp_device_info
 	return ret;
 }
 
-static unsigned int exynos_dp_process_equalizer_training(struct edp_device_info
-		*edp_info)
+static unsigned int exynos_dp_process_equalizer_training(
+		struct exynos_dp *regs, struct exynos_dp_priv *priv)
 {
 	unsigned int ret = EXYNOS_DP_SUCCESS;
 	unsigned char lane_stat, adj_req_sw, adj_req_em, i;
@@ -589,32 +604,33 @@ static unsigned int exynos_dp_process_equalizer_training(struct edp_device_info
 
 	mdelay(1);
 
-	ret = exynos_dp_read_dpcd_lane_stat(edp_info, &lane_stat);
+	ret = exynos_dp_read_dpcd_lane_stat(regs, priv, &lane_stat);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("DP read lane status failed\n");
-		edp_info->lt_info.lt_status = DP_LT_FAIL;
+		priv->lt_info.lt_status = DP_LT_FAIL;
 		return ret;
 	}
 
 	debug("DP lane stat : %x\n", lane_stat);
 
 	if (lane_stat & DP_LANE_STAT_CR_DONE) {
-		ret = exynos_dp_read_byte_from_dpcd(DPCD_LN_ALIGN_UPDATED,
-				&sink_stat);
+		ret = exynos_dp_read_byte_from_dpcd(regs,
+						    DPCD_LN_ALIGN_UPDATED,
+						    &sink_stat);
 		if (ret != EXYNOS_DP_SUCCESS) {
-			edp_info->lt_info.lt_status = DP_LT_FAIL;
+			priv->lt_info.lt_status = DP_LT_FAIL;
 
 			return ret;
 		}
 
 		interlane_aligned = (sink_stat & DPCD_INTERLANE_ALIGN_DONE);
 
-		for (i = 0; i < edp_info->lane_cnt; i++) {
-			ret = exynos_dp_read_dpcd_adj_req(i,
+		for (i = 0; i < priv->lane_cnt; i++) {
+			ret = exynos_dp_read_dpcd_adj_req(regs, i,
 					&adj_req_sw, &adj_req_em);
 			if (ret != EXYNOS_DP_SUCCESS) {
 				printf("DP read adj req 1 failed\n");
-				edp_info->lt_info.lt_status = DP_LT_FAIL;
+				priv->lt_info.lt_status = DP_LT_FAIL;
 
 				return ret;
 			}
@@ -634,86 +650,91 @@ static unsigned int exynos_dp_process_equalizer_training(struct edp_device_info
 			&& (interlane_aligned == DPCD_INTERLANE_ALIGN_DONE)) {
 			debug("DP Equalizer training succeed\n");
 
-			f_bw = exynos_dp_get_link_bandwidth();
-			f_lane_cnt = exynos_dp_get_lane_count();
+			f_bw = exynos_dp_get_link_bandwidth(regs);
+			f_lane_cnt = exynos_dp_get_lane_count(regs);
 
 			debug("DP final BandWidth : %x\n", f_bw);
 			debug("DP final Lane Count : %x\n", f_lane_cnt);
 
-			edp_info->lt_info.lt_status = DP_LT_FINISHED;
+			priv->lt_info.lt_status = DP_LT_FINISHED;
 
-			exynos_dp_equalizer_err_link(edp_info);
+			exynos_dp_equalizer_err_link(regs, priv);
 
 		} else {
-			edp_info->lt_info.ep_loop++;
+			priv->lt_info.ep_loop++;
 
-			if (edp_info->lt_info.ep_loop > MAX_EQ_LOOP) {
-				if (edp_info->lane_bw == DP_LANE_BW_2_70) {
+			if (priv->lt_info.ep_loop > MAX_EQ_LOOP) {
+				if (priv->lane_bw == DP_LANE_BW_2_70) {
 					ret = exynos_dp_reduce_link_rate(
-							edp_info);
+							regs, priv);
 				} else {
-					edp_info->lt_info.lt_status =
+					priv->lt_info.lt_status =
 								DP_LT_FAIL;
-					exynos_dp_equalizer_err_link(edp_info);
+					exynos_dp_equalizer_err_link(regs,
+								     priv);
 				}
 			} else {
-				for (i = 0; i < edp_info->lane_cnt; i++)
+				for (i = 0; i < priv->lane_cnt; i++)
 					exynos_dp_set_lanex_pre_emphasis(
-							lt_ctl_val[i], i);
+						regs, lt_ctl_val[i], i);
 
-				ret = exynos_dp_write_bytes_to_dpcd(
-					DPCD_TRAINING_LANE0_SET,
-					4, lt_ctl_val);
+				ret = exynos_dp_write_bytes_to_dpcd(regs,
+						DPCD_TRAINING_LANE0_SET,
+						4, lt_ctl_val);
 				if (ret != EXYNOS_DP_SUCCESS) {
 					printf("DP set lt pattern failed\n");
-					edp_info->lt_info.lt_status =
+					priv->lt_info.lt_status =
 								DP_LT_FAIL;
-					exynos_dp_equalizer_err_link(edp_info);
+					exynos_dp_equalizer_err_link(regs,
+								     priv);
 				}
 			}
 		}
-	} else if (edp_info->lane_bw == DP_LANE_BW_2_70) {
-		ret = exynos_dp_reduce_link_rate(edp_info);
+	} else if (priv->lane_bw == DP_LANE_BW_2_70) {
+		ret = exynos_dp_reduce_link_rate(regs, priv);
 	} else {
-		edp_info->lt_info.lt_status = DP_LT_FAIL;
-		exynos_dp_equalizer_err_link(edp_info);
+		priv->lt_info.lt_status = DP_LT_FAIL;
+		exynos_dp_equalizer_err_link(regs, priv);
 	}
 
 	return ret;
 }
 
-static unsigned int exynos_dp_sw_link_training(struct edp_device_info *edp_info)
+static unsigned int exynos_dp_sw_link_training(struct exynos_dp *regs,
+					       struct exynos_dp_priv *priv)
 {
 	unsigned int ret = 0;
 	int training_finished;
 
 	/* Turn off unnecessary lane */
-	if (edp_info->lane_cnt == 1)
-		exynos_dp_set_analog_power_down(CH1_BLOCK, 1);
+	if (priv->lane_cnt == 1)
+		exynos_dp_set_analog_power_down(regs, CH1_BLOCK, 1);
 
 	training_finished = 0;
 
-	edp_info->lt_info.lt_status = DP_LT_START;
+	priv->lt_info.lt_status = DP_LT_START;
 
 	/* Process here */
 	while (!training_finished) {
-		switch (edp_info->lt_info.lt_status) {
+		switch (priv->lt_info.lt_status) {
 		case DP_LT_START:
-			ret = exynos_dp_link_start(edp_info);
+			ret = exynos_dp_link_start(regs, priv);
 			if (ret != EXYNOS_DP_SUCCESS) {
 				printf("DP LT:link start failed\n");
 				return ret;
 			}
 			break;
 		case DP_LT_CR:
-			ret = exynos_dp_process_clock_recovery(edp_info);
+			ret = exynos_dp_process_clock_recovery(regs,
+							       priv);
 			if (ret != EXYNOS_DP_SUCCESS) {
 				printf("DP LT:clock recovery failed\n");
 				return ret;
 			}
 			break;
 		case DP_LT_ET:
-			ret = exynos_dp_process_equalizer_training(edp_info);
+			ret = exynos_dp_process_equalizer_training(regs,
+								   priv);
 			if (ret != EXYNOS_DP_SUCCESS) {
 				printf("DP LT:equalizer training failed\n");
 				return ret;
@@ -730,71 +751,75 @@ static unsigned int exynos_dp_sw_link_training(struct edp_device_info *edp_info)
 	return ret;
 }
 
-static unsigned int exynos_dp_set_link_train(struct edp_device_info *edp_info)
+static unsigned int exynos_dp_set_link_train(struct exynos_dp *regs,
+					     struct exynos_dp_priv *priv)
 {
 	unsigned int ret;
 
-	exynos_dp_init_training();
+	exynos_dp_init_training(regs);
 
-	ret = exynos_dp_sw_link_training(edp_info);
+	ret = exynos_dp_sw_link_training(regs, priv);
 	if (ret != EXYNOS_DP_SUCCESS)
 		printf("DP dp_sw_link_training() failed\n");
 
 	return ret;
 }
 
-static void exynos_dp_enable_scramble(unsigned int enable)
+static void exynos_dp_enable_scramble(struct exynos_dp *regs,
+				      unsigned int enable)
 {
 	unsigned char data;
 
 	if (enable) {
-		exynos_dp_enable_scrambling(DP_ENABLE);
+		exynos_dp_enable_scrambling(regs, DP_ENABLE);
 
-		exynos_dp_read_byte_from_dpcd(DPCD_TRAINING_PATTERN_SET,
-				&data);
-		exynos_dp_write_byte_to_dpcd(DPCD_TRAINING_PATTERN_SET,
+		exynos_dp_read_byte_from_dpcd(regs,
+					      DPCD_TRAINING_PATTERN_SET, &data);
+		exynos_dp_write_byte_to_dpcd(regs, DPCD_TRAINING_PATTERN_SET,
 			(u8)(data & ~DPCD_SCRAMBLING_DISABLED));
 	} else {
-		exynos_dp_enable_scrambling(DP_DISABLE);
-		exynos_dp_read_byte_from_dpcd(DPCD_TRAINING_PATTERN_SET,
-				&data);
-		exynos_dp_write_byte_to_dpcd(DPCD_TRAINING_PATTERN_SET,
+		exynos_dp_enable_scrambling(regs, DP_DISABLE);
+		exynos_dp_read_byte_from_dpcd(regs,
+					      DPCD_TRAINING_PATTERN_SET, &data);
+		exynos_dp_write_byte_to_dpcd(regs, DPCD_TRAINING_PATTERN_SET,
 			(u8)(data | DPCD_SCRAMBLING_DISABLED));
 	}
 }
 
-static unsigned int exynos_dp_config_video(struct edp_device_info *edp_info)
+static unsigned int exynos_dp_config_video(struct exynos_dp *regs,
+					   struct exynos_dp_priv *priv)
 {
 	unsigned int ret = 0;
 	unsigned int retry_cnt;
 
 	mdelay(1);
 
-	if (edp_info->video_info.master_mode) {
+	if (priv->video_info.master_mode) {
 		printf("DP does not support master mode\n");
 		return -ENODEV;
 	} else {
 		/* debug slave */
-		exynos_dp_config_video_slave_mode(&edp_info->video_info);
+		exynos_dp_config_video_slave_mode(regs,
+						  &priv->video_info);
 	}
 
-	exynos_dp_set_video_color_format(&edp_info->video_info);
+	exynos_dp_set_video_color_format(regs, &priv->video_info);
 
-	if (edp_info->video_info.bist_mode) {
-		if (exynos_dp_config_video_bist(edp_info) != 0)
+	if (priv->video_info.bist_mode) {
+		if (exynos_dp_config_video_bist(regs, priv) != 0)
 			return -1;
 	}
 
-	ret = exynos_dp_get_pll_lock_status();
+	ret = exynos_dp_get_pll_lock_status(regs);
 	if (ret != PLL_LOCKED) {
 		printf("DP PLL is not locked yet\n");
 		return -EIO;
 	}
 
-	if (edp_info->video_info.master_mode == 0) {
+	if (priv->video_info.master_mode == 0) {
 		retry_cnt = 10;
 		while (retry_cnt) {
-			ret = exynos_dp_is_slave_video_stream_clock_on();
+			ret = exynos_dp_is_slave_video_stream_clock_on(regs);
 			if (ret != EXYNOS_DP_SUCCESS) {
 				if (retry_cnt == 0) {
 					printf("DP stream_clock_on failed\n");
@@ -808,32 +833,34 @@ static unsigned int exynos_dp_config_video(struct edp_device_info *edp_info)
 	}
 
 	/* Set to use the register calculated M/N video */
-	exynos_dp_set_video_cr_mn(CALCULATED_M, 0, 0);
+	exynos_dp_set_video_cr_mn(regs, CALCULATED_M, 0, 0);
 
 	/* For video bist, Video timing must be generated by register */
-	exynos_dp_set_video_timing_mode(VIDEO_TIMING_FROM_CAPTURE);
+	exynos_dp_set_video_timing_mode(regs, VIDEO_TIMING_FROM_CAPTURE);
 
 	/* Enable video bist */
-	if (edp_info->video_info.bist_pattern != COLOR_RAMP &&
-		edp_info->video_info.bist_pattern != BALCK_WHITE_V_LINES &&
-		edp_info->video_info.bist_pattern != COLOR_SQUARE)
-		exynos_dp_enable_video_bist(edp_info->video_info.bist_mode);
+	if (priv->video_info.bist_pattern != COLOR_RAMP &&
+		priv->video_info.bist_pattern != BALCK_WHITE_V_LINES &&
+		priv->video_info.bist_pattern != COLOR_SQUARE)
+		exynos_dp_enable_video_bist(regs,
+					    priv->video_info.bist_mode);
 	else
-		exynos_dp_enable_video_bist(DP_DISABLE);
+		exynos_dp_enable_video_bist(regs, DP_DISABLE);
 
 	/* Disable video mute */
-	exynos_dp_enable_video_mute(DP_DISABLE);
+	exynos_dp_enable_video_mute(regs, DP_DISABLE);
 
 	/* Configure video Master or Slave mode */
-	exynos_dp_enable_video_master(edp_info->video_info.master_mode);
+	exynos_dp_enable_video_master(regs,
+				      priv->video_info.master_mode);
 
 	/* Enable video */
-	exynos_dp_start_video();
+	exynos_dp_start_video(regs);
 
-	if (edp_info->video_info.master_mode == 0) {
+	if (priv->video_info.master_mode == 0) {
 		retry_cnt = 100;
 		while (retry_cnt) {
-			ret = exynos_dp_is_video_stream_on();
+			ret = exynos_dp_is_video_stream_on(regs);
 			if (ret != EXYNOS_DP_SUCCESS) {
 				if (retry_cnt == 0) {
 					printf("DP Timeout of video stream\n");
@@ -849,107 +876,184 @@ static unsigned int exynos_dp_config_video(struct edp_device_info *edp_info)
 	return ret;
 }
 
-int exynos_dp_parse_dt(const void *blob, struct edp_device_info *edp_info)
+static int exynos_dp_ofdata_to_platdata(struct udevice *dev)
 {
-	unsigned int node = fdtdec_next_compatible(blob, 0,
-						COMPAT_SAMSUNG_EXYNOS5_DP);
-	if (node <= 0) {
-		debug("exynos_dp: Can't get device node for dp\n");
-		return -ENODEV;
+	struct exynos_dp_priv *priv = dev_get_priv(dev);
+	const void *blob = gd->fdt_blob;
+	unsigned int node = dev->of_offset;
+	fdt_addr_t addr;
+
+	addr = dev_get_addr(dev);
+	if (addr == FDT_ADDR_T_NONE) {
+		debug("Can't get the DP base address\n");
+		return -EINVAL;
 	}
-
-	edp_info->disp_info.h_res = fdtdec_get_int(blob, node,
+	priv->regs = (struct exynos_dp *)addr;
+	priv->disp_info.h_res = fdtdec_get_int(blob, node,
 							"samsung,h-res", 0);
-	edp_info->disp_info.h_sync_width = fdtdec_get_int(blob, node,
+	priv->disp_info.h_sync_width = fdtdec_get_int(blob, node,
 						"samsung,h-sync-width", 0);
-	edp_info->disp_info.h_back_porch = fdtdec_get_int(blob, node,
+	priv->disp_info.h_back_porch = fdtdec_get_int(blob, node,
 						"samsung,h-back-porch", 0);
-	edp_info->disp_info.h_front_porch = fdtdec_get_int(blob, node,
+	priv->disp_info.h_front_porch = fdtdec_get_int(blob, node,
 						"samsung,h-front-porch", 0);
-	edp_info->disp_info.v_res = fdtdec_get_int(blob, node,
+	priv->disp_info.v_res = fdtdec_get_int(blob, node,
 						"samsung,v-res", 0);
-	edp_info->disp_info.v_sync_width = fdtdec_get_int(blob, node,
+	priv->disp_info.v_sync_width = fdtdec_get_int(blob, node,
 						"samsung,v-sync-width", 0);
-	edp_info->disp_info.v_back_porch = fdtdec_get_int(blob, node,
+	priv->disp_info.v_back_porch = fdtdec_get_int(blob, node,
 						"samsung,v-back-porch", 0);
-	edp_info->disp_info.v_front_porch = fdtdec_get_int(blob, node,
+	priv->disp_info.v_front_porch = fdtdec_get_int(blob, node,
 						"samsung,v-front-porch", 0);
-	edp_info->disp_info.v_sync_rate = fdtdec_get_int(blob, node,
+	priv->disp_info.v_sync_rate = fdtdec_get_int(blob, node,
 						"samsung,v-sync-rate", 0);
 
-	edp_info->lt_info.lt_status = fdtdec_get_int(blob, node,
+	priv->lt_info.lt_status = fdtdec_get_int(blob, node,
 						"samsung,lt-status", 0);
 
-	edp_info->video_info.master_mode = fdtdec_get_int(blob, node,
+	priv->video_info.master_mode = fdtdec_get_int(blob, node,
 						"samsung,master-mode", 0);
-	edp_info->video_info.bist_mode = fdtdec_get_int(blob, node,
+	priv->video_info.bist_mode = fdtdec_get_int(blob, node,
 						"samsung,bist-mode", 0);
-	edp_info->video_info.bist_pattern = fdtdec_get_int(blob, node,
+	priv->video_info.bist_pattern = fdtdec_get_int(blob, node,
 						"samsung,bist-pattern", 0);
-	edp_info->video_info.h_sync_polarity = fdtdec_get_int(blob, node,
+	priv->video_info.h_sync_polarity = fdtdec_get_int(blob, node,
 						"samsung,h-sync-polarity", 0);
-	edp_info->video_info.v_sync_polarity = fdtdec_get_int(blob, node,
+	priv->video_info.v_sync_polarity = fdtdec_get_int(blob, node,
 						"samsung,v-sync-polarity", 0);
-	edp_info->video_info.interlaced = fdtdec_get_int(blob, node,
+	priv->video_info.interlaced = fdtdec_get_int(blob, node,
 						"samsung,interlaced", 0);
-	edp_info->video_info.color_space = fdtdec_get_int(blob, node,
+	priv->video_info.color_space = fdtdec_get_int(blob, node,
 						"samsung,color-space", 0);
-	edp_info->video_info.dynamic_range = fdtdec_get_int(blob, node,
+	priv->video_info.dynamic_range = fdtdec_get_int(blob, node,
 						"samsung,dynamic-range", 0);
-	edp_info->video_info.ycbcr_coeff = fdtdec_get_int(blob, node,
+	priv->video_info.ycbcr_coeff = fdtdec_get_int(blob, node,
 						"samsung,ycbcr-coeff", 0);
-	edp_info->video_info.color_depth = fdtdec_get_int(blob, node,
+	priv->video_info.color_depth = fdtdec_get_int(blob, node,
 						"samsung,color-depth", 0);
 	return 0;
 }
 
-unsigned int exynos_init_dp(void)
+static int exynos_dp_bridge_init(struct udevice *dev)
 {
-	unsigned int ret;
-	struct edp_device_info *edp_info;
+	const int max_tries = 10;
+	int num_tries;
+	int ret;
+
+	debug("%s\n", __func__);
+	ret = video_bridge_attach(dev);
+	if (ret) {
+		debug("video bridge init failed: %d\n", ret);
+		return ret;
+	}
+
+	/*
+	 * We need to wait for 90ms after bringing up the bridge since there
+	 * is a phantom "high" on the HPD chip during its bootup.  The phantom
+	 * high comes within 7ms of de-asserting PD and persists for at least
+	 * 15ms.  The real high comes roughly 50ms after PD is de-asserted. The
+	 * phantom high makes it hard for us to know when the NXP chip is up.
+	 */
+	mdelay(90);
+
+	for (num_tries = 0; num_tries < max_tries; num_tries++) {
+		/* Check HPD. If it's high, or we don't have it, all is well */
+		ret = video_bridge_check_attached(dev);
+		if (!ret || ret == -ENOENT)
+			return 0;
+
+		debug("%s: eDP bridge failed to come up; try %d of %d\n",
+		      __func__, num_tries, max_tries);
+	}
+
+	/* Immediately go into bridge reset if the hp line is not high */
+	return -EIO;
+}
+
+static int exynos_dp_bridge_setup(const void *blob)
+{
+	const int max_tries = 2;
+	int num_tries;
+	struct udevice *dev;
+	int ret;
 
-	edp_info = kzalloc(sizeof(struct edp_device_info), GFP_KERNEL);
-	if (!edp_info) {
-		debug("failed to allocate edp device object.\n");
-		return -EFAULT;
+	/* Configure I2C registers for Parade bridge */
+	ret = uclass_get_device(UCLASS_VIDEO_BRIDGE, 0, &dev);
+	if (ret) {
+		debug("video bridge init failed: %d\n", ret);
+		return ret;
 	}
 
-	if (exynos_dp_parse_dt(gd->fdt_blob, edp_info))
-		debug("unable to parse DP DT node\n");
+	if (strncmp(dev->driver->name, "parade", 6)) {
+		/* Mux HPHPD to the special hotplug detect mode */
+		exynos_pinmux_config(PERIPH_ID_DPHPD, 0);
+	}
 
-	exynos_dp_set_base_addr();
+	for (num_tries = 0; num_tries < max_tries; num_tries++) {
+		ret = exynos_dp_bridge_init(dev);
+		if (!ret)
+			return 0;
+		if (num_tries == max_tries - 1)
+			break;
 
-	exynos_dp_disp_info(&edp_info->disp_info);
+		/*
+		* If we're here, the bridge chip failed to initialise.
+		* Power down the bridge in an attempt to reset.
+		*/
+		video_bridge_set_active(dev, false);
+
+		/*
+		* Arbitrarily wait 300ms here with DP_N low.  Don't know for
+		* sure how long we should wait, but we're being paranoid.
+		*/
+		mdelay(300);
+	}
 
-	exynos_set_dp_phy(1);
+	return ret;
+}
+int exynos_dp_enable(struct udevice *dev, int panel_bpp,
+		     const struct display_timing *timing)
+{
+	struct exynos_dp_priv *priv = dev_get_priv(dev);
+	struct exynos_dp *regs = priv->regs;
+	unsigned int ret;
+
+	debug("%s: start\n", __func__);
+	exynos_dp_disp_info(&priv->disp_info);
+
+	ret = exynos_dp_bridge_setup(gd->fdt_blob);
+	if (ret && ret != -ENODEV)
+		printf("LCD bridge failed to enable: %d\n", ret);
 
-	ret = exynos_dp_init_dp();
+	exynos_dp_phy_ctrl(1);
+
+	ret = exynos_dp_init_dp(regs);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("DP exynos_dp_init_dp() failed\n");
 		return ret;
 	}
 
-	ret = exynos_dp_handle_edid(edp_info);
+	ret = exynos_dp_handle_edid(regs, priv);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("EDP handle_edid fail\n");
 		return ret;
 	}
 
-	ret = exynos_dp_set_link_train(edp_info);
+	ret = exynos_dp_set_link_train(regs, priv);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("DP link training fail\n");
 		return ret;
 	}
 
-	exynos_dp_enable_scramble(DP_ENABLE);
-	exynos_dp_enable_rx_to_enhanced_mode(DP_ENABLE);
-	exynos_dp_enable_enhanced_mode(DP_ENABLE);
+	exynos_dp_enable_scramble(regs, DP_ENABLE);
+	exynos_dp_enable_rx_to_enhanced_mode(regs, DP_ENABLE);
+	exynos_dp_enable_enhanced_mode(regs, DP_ENABLE);
 
-	exynos_dp_set_link_bandwidth(edp_info->lane_bw);
-	exynos_dp_set_lane_count(edp_info->lane_cnt);
+	exynos_dp_set_link_bandwidth(regs, priv->lane_bw);
+	exynos_dp_set_lane_count(regs, priv->lane_cnt);
 
-	exynos_dp_init_video();
-	ret = exynos_dp_config_video(edp_info);
+	exynos_dp_init_video(regs);
+	ret = exynos_dp_config_video(regs, priv);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("Exynos DP init failed\n");
 		return ret;
@@ -959,3 +1063,22 @@ unsigned int exynos_init_dp(void)
 
 	return ret;
 }
+
+
+static const struct dm_display_ops exynos_dp_ops = {
+	.enable = exynos_dp_enable,
+};
+
+static const struct udevice_id exynos_dp_ids[] = {
+	{ .compatible = "samsung,exynos5-dp" },
+	{ }
+};
+
+U_BOOT_DRIVER(exynos_dp) = {
+	.name	= "eexynos_dp",
+	.id	= UCLASS_DISPLAY,
+	.of_match = exynos_dp_ids,
+	.ops	= &exynos_dp_ops,
+	.ofdata_to_platdata	= exynos_dp_ofdata_to_platdata,
+	.priv_auto_alloc_size	= sizeof(struct exynos_dp_priv),
+};
diff --git a/drivers/video/exynos_dp_lowlevel.c b/drivers/video/exynos/exynos_dp_lowlevel.c
similarity index 77%
rename from drivers/video/exynos_dp_lowlevel.c
rename to drivers/video/exynos/exynos_dp_lowlevel.c
index acb5bc8eb7bb5986cf20ebf505100b72ad71a68a..f9784738bb959d4db604b9d01d69594e0eca9a42 100644
--- a/drivers/video/exynos_dp_lowlevel.c
+++ b/drivers/video/exynos/exynos_dp_lowlevel.c
@@ -14,30 +14,13 @@
 #include <asm/arch/dp.h>
 #include <fdtdec.h>
 #include <libfdt.h>
+#include "exynos_dp_lowlevel.h"
 
 /* Declare global data pointer */
 DECLARE_GLOBAL_DATA_PTR;
 
-struct exynos_dp *dp_regs;
-
-void exynos_dp_set_base_addr(void)
-{
-#if CONFIG_IS_ENABLED(OF_CONTROL)
-	unsigned int node = fdtdec_next_compatible(gd->fdt_blob,
-					0, COMPAT_SAMSUNG_EXYNOS5_DP);
-	if (node <= 0)
-		debug("exynos_dp: Can't get device node for dp\n");
-
-	dp_regs = (struct exynos_dp *)fdtdec_get_addr(gd->fdt_blob,
-								node, "reg");
-	if (dp_regs == NULL)
-		debug("Can't get the DP base address\n");
-#else
-	dp_regs = (struct exynos_dp *)samsung_get_base_dp();
-#endif
-}
-
-static void exynos_dp_enable_video_input(unsigned int enable)
+static void exynos_dp_enable_video_input(struct exynos_dp *dp_regs,
+					 unsigned int enable)
 {
 	unsigned int reg;
 
@@ -53,7 +36,7 @@ static void exynos_dp_enable_video_input(unsigned int enable)
 	return;
 }
 
-void exynos_dp_enable_video_bist(unsigned int enable)
+void exynos_dp_enable_video_bist(struct exynos_dp *dp_regs, unsigned int enable)
 {
 	/* enable video bist */
 	unsigned int reg;
@@ -70,7 +53,7 @@ void exynos_dp_enable_video_bist(unsigned int enable)
 	return;
 }
 
-void exynos_dp_enable_video_mute(unsigned int enable)
+void exynos_dp_enable_video_mute(struct exynos_dp *dp_regs, unsigned int enable)
 {
 	unsigned int reg;
 
@@ -85,7 +68,7 @@ void exynos_dp_enable_video_mute(unsigned int enable)
 }
 
 
-static void exynos_dp_init_analog_param(void)
+static void exynos_dp_init_analog_param(struct exynos_dp *dp_regs)
 {
 	unsigned int reg;
 
@@ -134,7 +117,7 @@ static void exynos_dp_init_analog_param(void)
 	writel(reg, &dp_regs->pll_ctl);
 }
 
-static void exynos_dp_init_interrupt(void)
+static void exynos_dp_init_interrupt(struct exynos_dp *dp_regs)
 {
 	/* Set interrupt registers to initial states */
 
@@ -161,16 +144,16 @@ static void exynos_dp_init_interrupt(void)
 	writel(0x00, &dp_regs->int_sta_mask);
 }
 
-void exynos_dp_reset(void)
+void exynos_dp_reset(struct exynos_dp *dp_regs)
 {
 	unsigned int reg_func_1;
 
 	/* dp tx sw reset */
 	writel(RESET_DP_TX, &dp_regs->tx_sw_reset);
 
-	exynos_dp_enable_video_input(DP_DISABLE);
-	exynos_dp_enable_video_bist(DP_DISABLE);
-	exynos_dp_enable_video_mute(DP_DISABLE);
+	exynos_dp_enable_video_input(dp_regs, DP_DISABLE);
+	exynos_dp_enable_video_bist(dp_regs, DP_DISABLE);
+	exynos_dp_enable_video_mute(dp_regs, DP_DISABLE);
 
 	/* software reset */
 	reg_func_1 = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
@@ -182,13 +165,13 @@ void exynos_dp_reset(void)
 
 	mdelay(1);
 
-	exynos_dp_init_analog_param();
-	exynos_dp_init_interrupt();
+	exynos_dp_init_analog_param(dp_regs);
+	exynos_dp_init_interrupt(dp_regs);
 
 	return;
 }
 
-void exynos_dp_enable_sw_func(unsigned int enable)
+void exynos_dp_enable_sw_func(struct exynos_dp *dp_regs, unsigned int enable)
 {
 	unsigned int reg;
 
@@ -203,7 +186,8 @@ void exynos_dp_enable_sw_func(unsigned int enable)
 	return;
 }
 
-unsigned int exynos_dp_set_analog_power_down(unsigned int block, u32 enable)
+unsigned int exynos_dp_set_analog_power_down(struct exynos_dp *dp_regs,
+					     unsigned int block, u32 enable)
 {
 	unsigned int reg;
 
@@ -256,7 +240,7 @@ unsigned int exynos_dp_set_analog_power_down(unsigned int block, u32 enable)
 	return 0;
 }
 
-unsigned int exynos_dp_get_pll_lock_status(void)
+unsigned int exynos_dp_get_pll_lock_status(struct exynos_dp *dp_regs)
 {
 	unsigned int reg;
 
@@ -268,7 +252,8 @@ unsigned int exynos_dp_get_pll_lock_status(void)
 		return PLL_UNLOCKED;
 }
 
-static void exynos_dp_set_pll_power(unsigned int enable)
+static void exynos_dp_set_pll_power(struct exynos_dp *dp_regs,
+				    unsigned int enable)
 {
 	unsigned int reg;
 
@@ -281,14 +266,14 @@ static void exynos_dp_set_pll_power(unsigned int enable)
 	writel(reg, &dp_regs->pll_ctl);
 }
 
-int exynos_dp_init_analog_func(void)
+int exynos_dp_init_analog_func(struct exynos_dp *dp_regs)
 {
 	int ret = EXYNOS_DP_SUCCESS;
 	unsigned int retry_cnt = 10;
 	unsigned int reg;
 
 	/* Power On All Analog block */
-	exynos_dp_set_analog_power_down(POWER_ALL, DP_DISABLE);
+	exynos_dp_set_analog_power_down(dp_regs, POWER_ALL, DP_DISABLE);
 
 	reg = PLL_LOCK_CHG;
 	writel(reg, &dp_regs->common_int_sta1);
@@ -309,9 +294,9 @@ int exynos_dp_init_analog_func(void)
 	reg &= ~(DP_PLL_RESET);
 	writel(reg, &dp_regs->pll_ctl);
 
-	exynos_dp_set_pll_power(DP_ENABLE);
+	exynos_dp_set_pll_power(dp_regs, DP_ENABLE);
 
-	while (exynos_dp_get_pll_lock_status() == PLL_UNLOCKED) {
+	while (exynos_dp_get_pll_lock_status(dp_regs) == PLL_UNLOCKED) {
 		mdelay(1);
 		retry_cnt--;
 		if (retry_cnt == 0) {
@@ -332,7 +317,7 @@ int exynos_dp_init_analog_func(void)
 	return ret;
 }
 
-void exynos_dp_init_hpd(void)
+void exynos_dp_init_hpd(struct exynos_dp *dp_regs)
 {
 	unsigned int reg;
 
@@ -350,7 +335,7 @@ void exynos_dp_init_hpd(void)
 	return;
 }
 
-static inline void exynos_dp_reset_aux(void)
+static inline void exynos_dp_reset_aux(struct exynos_dp *dp_regs)
 {
 	unsigned int reg;
 
@@ -362,7 +347,7 @@ static inline void exynos_dp_reset_aux(void)
 	return;
 }
 
-void exynos_dp_init_aux(void)
+void exynos_dp_init_aux(struct exynos_dp *dp_regs)
 {
 	unsigned int reg;
 
@@ -370,7 +355,7 @@ void exynos_dp_init_aux(void)
 	reg = RPLY_RECEIV | AUX_ERR;
 	writel(reg, &dp_regs->int_sta);
 
-	exynos_dp_reset_aux();
+	exynos_dp_reset_aux(dp_regs);
 
 	/* Disable AUX transaction H/W retry */
 	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(3)|
@@ -389,7 +374,7 @@ void exynos_dp_init_aux(void)
 	return;
 }
 
-void exynos_dp_config_interrupt(void)
+void exynos_dp_config_interrupt(struct exynos_dp *dp_regs)
 {
 	unsigned int reg;
 
@@ -412,7 +397,7 @@ void exynos_dp_config_interrupt(void)
 	return;
 }
 
-unsigned int exynos_dp_get_plug_in_status(void)
+unsigned int exynos_dp_get_plug_in_status(struct exynos_dp *dp_regs)
 {
 	unsigned int reg;
 
@@ -423,13 +408,13 @@ unsigned int exynos_dp_get_plug_in_status(void)
 	return -1;
 }
 
-unsigned int exynos_dp_detect_hpd(void)
+unsigned int exynos_dp_detect_hpd(struct exynos_dp *dp_regs)
 {
 	int timeout_loop = DP_TIMEOUT_LOOP_COUNT;
 
 	mdelay(2);
 
-	while (exynos_dp_get_plug_in_status() != 0) {
+	while (exynos_dp_get_plug_in_status(dp_regs) != 0) {
 		if (timeout_loop == 0)
 			return -EINVAL;
 		mdelay(10);
@@ -439,7 +424,7 @@ unsigned int exynos_dp_detect_hpd(void)
 	return EXYNOS_DP_SUCCESS;
 }
 
-unsigned int exynos_dp_start_aux_transaction(void)
+unsigned int exynos_dp_start_aux_transaction(struct exynos_dp *dp_regs)
 {
 	unsigned int reg;
 	unsigned int ret = 0;
@@ -488,8 +473,9 @@ unsigned int exynos_dp_start_aux_transaction(void)
 	return EXYNOS_DP_SUCCESS;
 }
 
-unsigned int exynos_dp_write_byte_to_dpcd(unsigned int reg_addr,
-				unsigned char data)
+unsigned int exynos_dp_write_byte_to_dpcd(struct exynos_dp *dp_regs,
+					  unsigned int reg_addr,
+					  unsigned char data)
 {
 	unsigned int reg, ret;
 
@@ -518,7 +504,7 @@ unsigned int exynos_dp_write_byte_to_dpcd(unsigned int reg_addr,
 	writel(reg, &dp_regs->aux_ch_ctl1);
 
 	/* Start AUX transaction */
-	ret = exynos_dp_start_aux_transaction();
+	ret = exynos_dp_start_aux_transaction(dp_regs);
 	if (ret != EXYNOS_DP_SUCCESS) {
 		printf("DP Aux transaction failed\n");
 		return ret;
@@ -527,8 +513,9 @@ unsigned int exynos_dp_write_byte_to_dpcd(unsigned int reg_addr,
 	return ret;
 }
 
-unsigned int exynos_dp_read_byte_from_dpcd(unsigned int reg_addr,
-		unsigned char *data)
+unsigned int exynos_dp_read_byte_from_dpcd(struct exynos_dp *dp_regs,
+					   unsigned int reg_addr,
+					   unsigned char *data)
 {
 	unsigned int reg;
 	int retval;
@@ -554,7 +541,7 @@ unsigned int exynos_dp_read_byte_from_dpcd(unsigned int reg_addr,
 	writel(reg, &dp_regs->aux_ch_ctl1);
 
 	/* Start AUX transaction */
-	retval = exynos_dp_start_aux_transaction();
+	retval = exynos_dp_start_aux_transaction(dp_regs);
 	if (!retval)
 		debug("DP Aux Transaction fail!\n");
 
@@ -565,9 +552,10 @@ unsigned int exynos_dp_read_byte_from_dpcd(unsigned int reg_addr,
 	return retval;
 }
 
-unsigned int exynos_dp_write_bytes_to_dpcd(unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[])
+unsigned int exynos_dp_write_bytes_to_dpcd(struct exynos_dp *dp_regs,
+					   unsigned int reg_addr,
+					   unsigned int count,
+					   unsigned char data[])
 {
 	unsigned int reg;
 	unsigned int start_offset;
@@ -614,7 +602,7 @@ unsigned int exynos_dp_write_bytes_to_dpcd(unsigned int reg_addr,
 			writel(reg, &dp_regs->aux_ch_ctl1);
 
 			/* Start AUX transaction */
-			ret = exynos_dp_start_aux_transaction();
+			ret = exynos_dp_start_aux_transaction(dp_regs);
 			if (ret != EXYNOS_DP_SUCCESS) {
 				if (retry_cnt == 0) {
 					printf("DP Aux Transaction failed\n");
@@ -630,9 +618,10 @@ unsigned int exynos_dp_write_bytes_to_dpcd(unsigned int reg_addr,
 	return ret;
 }
 
-unsigned int exynos_dp_read_bytes_from_dpcd(unsigned int reg_addr,
-				unsigned int count,
-				unsigned char data[])
+unsigned int exynos_dp_read_bytes_from_dpcd(struct exynos_dp *dp_regs,
+					    unsigned int reg_addr,
+					    unsigned int count,
+					    unsigned char data[])
 {
 	unsigned int reg;
 	unsigned int start_offset;
@@ -672,7 +661,7 @@ unsigned int exynos_dp_read_bytes_from_dpcd(unsigned int reg_addr,
 			writel(reg, &dp_regs->aux_ch_ctl1);
 
 			/* Start AUX transaction */
-			ret = exynos_dp_start_aux_transaction();
+			ret = exynos_dp_start_aux_transaction(dp_regs);
 			if (ret != EXYNOS_DP_SUCCESS) {
 				if (retry_cnt == 0) {
 					printf("DP Aux Transaction failed\n");
@@ -696,8 +685,8 @@ unsigned int exynos_dp_read_bytes_from_dpcd(unsigned int reg_addr,
 	return ret;
 }
 
-int exynos_dp_select_i2c_device(unsigned int device_addr,
-				unsigned int reg_addr)
+int exynos_dp_select_i2c_device(struct exynos_dp *dp_regs,
+				unsigned int device_addr, unsigned int reg_addr)
 {
 	unsigned int reg;
 	int retval;
@@ -721,16 +710,16 @@ int exynos_dp_select_i2c_device(unsigned int device_addr,
 	writel(reg, &dp_regs->aux_ch_ctl1);
 
 	/* Start AUX transaction */
-	retval = exynos_dp_start_aux_transaction();
+	retval = exynos_dp_start_aux_transaction(dp_regs);
 	if (retval != 0)
 		printf("%s: DP Aux Transaction fail!\n", __func__);
 
 	return retval;
 }
 
-int exynos_dp_read_byte_from_i2c(unsigned int device_addr,
-				unsigned int reg_addr,
-				unsigned int *data)
+int exynos_dp_read_byte_from_i2c(struct exynos_dp *dp_regs,
+				 unsigned int device_addr,
+				 unsigned int reg_addr, unsigned int *data)
 {
 	unsigned int reg;
 	int i;
@@ -742,7 +731,8 @@ int exynos_dp_read_byte_from_i2c(unsigned int device_addr,
 		writel(reg, &dp_regs->buffer_data_ctl);
 
 		/* Select EDID device */
-		retval = exynos_dp_select_i2c_device(device_addr, reg_addr);
+		retval = exynos_dp_select_i2c_device(dp_regs, device_addr,
+						     reg_addr);
 		if (retval != 0) {
 			printf("DP Select EDID device fail. retry !\n");
 			continue;
@@ -758,7 +748,7 @@ int exynos_dp_read_byte_from_i2c(unsigned int device_addr,
 		writel(reg, &dp_regs->aux_ch_ctl1);
 
 		/* Start AUX transaction */
-		retval = exynos_dp_start_aux_transaction();
+		retval = exynos_dp_start_aux_transaction(dp_regs);
 		if (retval != EXYNOS_DP_SUCCESS)
 			printf("%s: DP Aux Transaction fail!\n", __func__);
 	}
@@ -770,8 +760,10 @@ int exynos_dp_read_byte_from_i2c(unsigned int device_addr,
 	return retval;
 }
 
-int exynos_dp_read_bytes_from_i2c(unsigned int device_addr,
-		unsigned int reg_addr, unsigned int count, unsigned char edid[])
+int exynos_dp_read_bytes_from_i2c(struct exynos_dp *dp_regs,
+				  unsigned int device_addr,
+				  unsigned int reg_addr, unsigned int count,
+				  unsigned char edid[])
 {
 	unsigned int reg;
 	unsigned int i, j;
@@ -795,9 +787,8 @@ int exynos_dp_read_bytes_from_i2c(unsigned int device_addr,
 			 * request without sending addres
 			 */
 			if (!defer)
-				retval =
-					exynos_dp_select_i2c_device(device_addr,
-							reg_addr + i);
+				retval = exynos_dp_select_i2c_device(
+					dp_regs, device_addr, reg_addr + i);
 			else
 				defer = 0;
 
@@ -813,7 +804,8 @@ int exynos_dp_read_bytes_from_i2c(unsigned int device_addr,
 				writel(reg, &dp_regs->aux_ch_ctl1);
 
 				/* Start AUX transaction */
-				retval = exynos_dp_start_aux_transaction();
+				retval = exynos_dp_start_aux_transaction(
+							dp_regs);
 				if (retval == 0)
 					break;
 				else
@@ -838,7 +830,7 @@ int exynos_dp_read_bytes_from_i2c(unsigned int device_addr,
 	return retval;
 }
 
-void exynos_dp_reset_macro(void)
+void exynos_dp_reset_macro(struct exynos_dp *dp_regs)
 {
 	unsigned int reg;
 
@@ -853,7 +845,8 @@ void exynos_dp_reset_macro(void)
 	writel(reg, &dp_regs->phy_test);
 }
 
-void exynos_dp_set_link_bandwidth(unsigned char bwtype)
+void exynos_dp_set_link_bandwidth(struct exynos_dp *dp_regs,
+				  unsigned char bwtype)
 {
 	unsigned int reg;
 
@@ -864,7 +857,7 @@ void exynos_dp_set_link_bandwidth(unsigned char bwtype)
 		writel(reg, &dp_regs->link_bw_set);
 }
 
-unsigned char exynos_dp_get_link_bandwidth(void)
+unsigned char exynos_dp_get_link_bandwidth(struct exynos_dp *dp_regs)
 {
 	unsigned char ret;
 	unsigned int reg;
@@ -875,7 +868,7 @@ unsigned char exynos_dp_get_link_bandwidth(void)
 	return ret;
 }
 
-void exynos_dp_set_lane_count(unsigned char count)
+void exynos_dp_set_lane_count(struct exynos_dp *dp_regs, unsigned char count)
 {
 	unsigned int reg;
 
@@ -886,7 +879,7 @@ void exynos_dp_set_lane_count(unsigned char count)
 		writel(reg, &dp_regs->lane_count_set);
 }
 
-unsigned int exynos_dp_get_lane_count(void)
+unsigned int exynos_dp_get_lane_count(struct exynos_dp *dp_regs)
 {
 	unsigned int reg;
 
@@ -895,7 +888,8 @@ unsigned int exynos_dp_get_lane_count(void)
 	return reg;
 }
 
-unsigned char exynos_dp_get_lanex_pre_emphasis(unsigned char lanecnt)
+unsigned char exynos_dp_get_lanex_pre_emphasis(struct exynos_dp *dp_regs,
+					       unsigned char lanecnt)
 {
 	unsigned int reg_list[DP_LANE_CNT_4] = {
 		(unsigned int)&dp_regs->ln0_link_training_ctl,
@@ -907,8 +901,9 @@ unsigned char exynos_dp_get_lanex_pre_emphasis(unsigned char lanecnt)
 	return readl(reg_list[lanecnt]);
 }
 
-void exynos_dp_set_lanex_pre_emphasis(unsigned char request_val,
-		unsigned char lanecnt)
+void exynos_dp_set_lanex_pre_emphasis(struct exynos_dp *dp_regs,
+				      unsigned char request_val,
+				      unsigned char lanecnt)
 {
 	unsigned int reg_list[DP_LANE_CNT_4] = {
 		(unsigned int)&dp_regs->ln0_link_training_ctl,
@@ -920,7 +915,8 @@ void exynos_dp_set_lanex_pre_emphasis(unsigned char request_val,
 	writel(request_val, reg_list[lanecnt]);
 }
 
-void exynos_dp_set_lane_pre_emphasis(unsigned int level, unsigned char lanecnt)
+void exynos_dp_set_lane_pre_emphasis(struct exynos_dp *dp_regs,
+				     unsigned int level, unsigned char lanecnt)
 {
 	unsigned char i;
 	unsigned int reg;
@@ -943,7 +939,8 @@ void exynos_dp_set_lane_pre_emphasis(unsigned int level, unsigned char lanecnt)
 	}
 }
 
-void exynos_dp_set_training_pattern(unsigned int pattern)
+void exynos_dp_set_training_pattern(struct exynos_dp *dp_regs,
+				    unsigned int pattern)
 {
 	unsigned int reg = 0;
 
@@ -971,7 +968,8 @@ void exynos_dp_set_training_pattern(unsigned int pattern)
 	writel(reg, &dp_regs->training_ptn_set);
 }
 
-void exynos_dp_enable_enhanced_mode(unsigned char enable)
+void exynos_dp_enable_enhanced_mode(struct exynos_dp *dp_regs,
+				    unsigned char enable)
 {
 	unsigned int reg;
 
@@ -984,7 +982,7 @@ void exynos_dp_enable_enhanced_mode(unsigned char enable)
 	writel(reg, &dp_regs->sys_ctl4);
 }
 
-void exynos_dp_enable_scrambling(unsigned int enable)
+void exynos_dp_enable_scrambling(struct exynos_dp *dp_regs, unsigned int enable)
 {
 	unsigned int reg;
 
@@ -997,7 +995,7 @@ void exynos_dp_enable_scrambling(unsigned int enable)
 	writel(reg, &dp_regs->training_ptn_set);
 }
 
-int exynos_dp_init_video(void)
+int exynos_dp_init_video(struct exynos_dp *dp_regs)
 {
 	unsigned int reg;
 
@@ -1012,7 +1010,8 @@ int exynos_dp_init_video(void)
 	return 0;
 }
 
-void exynos_dp_config_video_slave_mode(struct edp_video_info *video_info)
+void exynos_dp_config_video_slave_mode(struct exynos_dp *dp_regs,
+				       struct edp_video_info *video_info)
 {
 	unsigned int reg;
 
@@ -1045,7 +1044,8 @@ void exynos_dp_config_video_slave_mode(struct edp_video_info *video_info)
 	writel(reg, &dp_regs->soc_general_ctl);
 }
 
-void exynos_dp_set_video_color_format(struct edp_video_info *video_info)
+void exynos_dp_set_video_color_format(struct exynos_dp *dp_regs,
+				      struct edp_video_info *video_info)
 {
 	unsigned int reg;
 
@@ -1065,49 +1065,47 @@ void exynos_dp_set_video_color_format(struct edp_video_info *video_info)
 	writel(reg, &dp_regs->video_ctl3);
 }
 
-int exynos_dp_config_video_bist(struct edp_device_info *edp_info)
+int exynos_dp_config_video_bist(struct exynos_dp *dp_regs,
+				struct exynos_dp_priv *priv)
 {
 	unsigned int reg;
 	unsigned int bist_type = 0;
-	struct edp_video_info video_info = edp_info->video_info;
+	struct edp_video_info video_info = priv->video_info;
 
 	/* For master mode, you don't need to set the video format */
 	if (video_info.master_mode == 0) {
-		writel(TOTAL_LINE_CFG_L(edp_info->disp_info.v_total),
-				&dp_regs->total_ln_cfg_l);
-		writel(TOTAL_LINE_CFG_H(edp_info->disp_info.v_total),
-				&dp_regs->total_ln_cfg_h);
-		writel(ACTIVE_LINE_CFG_L(edp_info->disp_info.v_res),
-				&dp_regs->active_ln_cfg_l);
-		writel(ACTIVE_LINE_CFG_H(edp_info->disp_info.v_res),
-				&dp_regs->active_ln_cfg_h);
-		writel(edp_info->disp_info.v_sync_width,
-				&dp_regs->vsw_cfg);
-		writel(edp_info->disp_info.v_back_porch,
-				&dp_regs->vbp_cfg);
-		writel(edp_info->disp_info.v_front_porch,
-				&dp_regs->vfp_cfg);
-
-		writel(TOTAL_PIXEL_CFG_L(edp_info->disp_info.h_total),
-				&dp_regs->total_pix_cfg_l);
-		writel(TOTAL_PIXEL_CFG_H(edp_info->disp_info.h_total),
-				&dp_regs->total_pix_cfg_h);
-		writel(ACTIVE_PIXEL_CFG_L(edp_info->disp_info.h_res),
-				&dp_regs->active_pix_cfg_l);
-		writel(ACTIVE_PIXEL_CFG_H(edp_info->disp_info.h_res),
-				&dp_regs->active_pix_cfg_h);
-		writel(H_F_PORCH_CFG_L(edp_info->disp_info.h_front_porch),
-				&dp_regs->hfp_cfg_l);
-		writel(H_F_PORCH_CFG_H(edp_info->disp_info.h_front_porch),
-				&dp_regs->hfp_cfg_h);
-		writel(H_SYNC_PORCH_CFG_L(edp_info->disp_info.h_sync_width),
-				&dp_regs->hsw_cfg_l);
-		writel(H_SYNC_PORCH_CFG_H(edp_info->disp_info.h_sync_width),
-				&dp_regs->hsw_cfg_h);
-		writel(H_B_PORCH_CFG_L(edp_info->disp_info.h_back_porch),
-				&dp_regs->hbp_cfg_l);
-		writel(H_B_PORCH_CFG_H(edp_info->disp_info.h_back_porch),
-				&dp_regs->hbp_cfg_h);
+		writel(TOTAL_LINE_CFG_L(priv->disp_info.v_total),
+		       &dp_regs->total_ln_cfg_l);
+		writel(TOTAL_LINE_CFG_H(priv->disp_info.v_total),
+		       &dp_regs->total_ln_cfg_h);
+		writel(ACTIVE_LINE_CFG_L(priv->disp_info.v_res),
+		       &dp_regs->active_ln_cfg_l);
+		writel(ACTIVE_LINE_CFG_H(priv->disp_info.v_res),
+		       &dp_regs->active_ln_cfg_h);
+		writel(priv->disp_info.v_sync_width, &dp_regs->vsw_cfg);
+		writel(priv->disp_info.v_back_porch, &dp_regs->vbp_cfg);
+		writel(priv->disp_info.v_front_porch, &dp_regs->vfp_cfg);
+
+		writel(TOTAL_PIXEL_CFG_L(priv->disp_info.h_total),
+		       &dp_regs->total_pix_cfg_l);
+		writel(TOTAL_PIXEL_CFG_H(priv->disp_info.h_total),
+		       &dp_regs->total_pix_cfg_h);
+		writel(ACTIVE_PIXEL_CFG_L(priv->disp_info.h_res),
+		       &dp_regs->active_pix_cfg_l);
+		writel(ACTIVE_PIXEL_CFG_H(priv->disp_info.h_res),
+		       &dp_regs->active_pix_cfg_h);
+		writel(H_F_PORCH_CFG_L(priv->disp_info.h_front_porch),
+		       &dp_regs->hfp_cfg_l);
+		writel(H_F_PORCH_CFG_H(priv->disp_info.h_front_porch),
+		       &dp_regs->hfp_cfg_h);
+		writel(H_SYNC_PORCH_CFG_L(priv->disp_info.h_sync_width),
+		       &dp_regs->hsw_cfg_l);
+		writel(H_SYNC_PORCH_CFG_H(priv->disp_info.h_sync_width),
+		       &dp_regs->hsw_cfg_h);
+		writel(H_B_PORCH_CFG_L(priv->disp_info.h_back_porch),
+		       &dp_regs->hbp_cfg_l);
+		writel(H_B_PORCH_CFG_H(priv->disp_info.h_back_porch),
+		       &dp_regs->hbp_cfg_h);
 
 		/*
 		 * Set SLAVE_I_SCAN_CFG[2], VSYNC_P_CFG[1],
@@ -1155,7 +1153,7 @@ int exynos_dp_config_video_bist(struct edp_device_info *edp_info)
 	return 0;
 }
 
-unsigned int exynos_dp_is_slave_video_stream_clock_on(void)
+unsigned int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp *dp_regs)
 {
 	unsigned int reg;
 
@@ -1173,8 +1171,8 @@ unsigned int exynos_dp_is_slave_video_stream_clock_on(void)
 	return EXYNOS_DP_SUCCESS;
 }
 
-void exynos_dp_set_video_cr_mn(unsigned int type, unsigned int m_value,
-		unsigned int n_value)
+void exynos_dp_set_video_cr_mn(struct exynos_dp *dp_regs, unsigned int type,
+			       unsigned int m_value, unsigned int n_value)
 {
 	unsigned int reg;
 
@@ -1202,7 +1200,8 @@ void exynos_dp_set_video_cr_mn(unsigned int type, unsigned int m_value,
 	}
 }
 
-void exynos_dp_set_video_timing_mode(unsigned int type)
+void exynos_dp_set_video_timing_mode(struct exynos_dp *dp_regs,
+				     unsigned int type)
 {
 	unsigned int reg;
 
@@ -1215,7 +1214,8 @@ void exynos_dp_set_video_timing_mode(unsigned int type)
 	writel(reg, &dp_regs->video_ctl10);
 }
 
-void exynos_dp_enable_video_master(unsigned int enable)
+void exynos_dp_enable_video_master(struct exynos_dp *dp_regs,
+				   unsigned int enable)
 {
 	unsigned int reg;
 
@@ -1231,7 +1231,7 @@ void exynos_dp_enable_video_master(unsigned int enable)
 	writel(reg, &dp_regs->soc_general_ctl);
 }
 
-void exynos_dp_start_video(void)
+void exynos_dp_start_video(struct exynos_dp *dp_regs)
 {
 	unsigned int reg;
 
@@ -1241,7 +1241,7 @@ void exynos_dp_start_video(void)
 	writel(reg, &dp_regs->video_ctl1);
 }
 
-unsigned int exynos_dp_is_video_stream_on(void)
+unsigned int exynos_dp_is_video_stream_on(struct exynos_dp *dp_regs)
 {
 	unsigned int reg;
 
diff --git a/drivers/video/exynos/exynos_dp_lowlevel.h b/drivers/video/exynos/exynos_dp_lowlevel.h
new file mode 100644
index 0000000000000000000000000000000000000000..e4c867eef04ca2f8e2decfd4932b8a578b6a67b8
--- /dev/null
+++ b/drivers/video/exynos/exynos_dp_lowlevel.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * Author: Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _EXYNOS_EDP_LOWLEVEL_H
+#define _EXYNOS_EDP_LOWLEVEL_H
+
+void exynos_dp_enable_video_bist(struct exynos_dp *dp_regs,
+				 unsigned int enable);
+void exynos_dp_enable_video_mute(struct exynos_dp *dp_regs,
+				 unsigned int enable);
+void exynos_dp_reset(struct exynos_dp *dp_regs);
+void exynos_dp_enable_sw_func(struct exynos_dp *dp_regs, unsigned int enable);
+unsigned int exynos_dp_set_analog_power_down(struct exynos_dp *dp_regs,
+					     unsigned int block, u32 enable);
+unsigned int exynos_dp_get_pll_lock_status(struct exynos_dp *dp_regs);
+int exynos_dp_init_analog_func(struct exynos_dp *dp_regs);
+void exynos_dp_init_hpd(struct exynos_dp *dp_regs);
+void exynos_dp_init_aux(struct exynos_dp *dp_regs);
+void exynos_dp_config_interrupt(struct exynos_dp *dp_regs);
+unsigned int exynos_dp_get_plug_in_status(struct exynos_dp *dp_regs);
+unsigned int exynos_dp_detect_hpd(struct exynos_dp *dp_regs);
+unsigned int exynos_dp_start_aux_transaction(struct exynos_dp *dp_regs);
+unsigned int exynos_dp_write_byte_to_dpcd(struct exynos_dp *dp_regs,
+					  unsigned int reg_addr,
+					  unsigned char data);
+unsigned int exynos_dp_read_byte_from_dpcd(struct exynos_dp *dp_regs,
+					   unsigned int reg_addr,
+					   unsigned char *data);
+unsigned int exynos_dp_write_bytes_to_dpcd(struct exynos_dp *dp_regs,
+					   unsigned int reg_addr,
+					   unsigned int count,
+					   unsigned char data[]);
+unsigned int exynos_dp_read_bytes_from_dpcd(struct exynos_dp *dp_regs,
+					    unsigned int reg_addr,
+					    unsigned int count,
+					    unsigned char data[]);
+int exynos_dp_select_i2c_device(struct exynos_dp *dp_regs,
+				unsigned int device_addr,
+				unsigned int reg_addr);
+int exynos_dp_read_byte_from_i2c(struct exynos_dp *dp_regs,
+				 unsigned int device_addr,
+				 unsigned int reg_addr, unsigned int *data);
+int exynos_dp_read_bytes_from_i2c(struct exynos_dp *dp_regs,
+				  unsigned int device_addr,
+				  unsigned int reg_addr, unsigned int count,
+				  unsigned char edid[]);
+void exynos_dp_reset_macro(struct exynos_dp *dp_regs);
+void exynos_dp_set_link_bandwidth(struct exynos_dp *dp_regs,
+				  unsigned char bwtype);
+unsigned char exynos_dp_get_link_bandwidth(struct exynos_dp *dp_regs);
+void exynos_dp_set_lane_count(struct exynos_dp *dp_regs, unsigned char count);
+unsigned int exynos_dp_get_lane_count(struct exynos_dp *dp_regs);
+unsigned char exynos_dp_get_lanex_pre_emphasis(struct exynos_dp *dp_regs,
+					       unsigned char lanecnt);
+void exynos_dp_set_lane_pre_emphasis(struct exynos_dp *dp_regs,
+				     unsigned int level, unsigned char lanecnt);
+void exynos_dp_set_lanex_pre_emphasis(struct exynos_dp *dp_regs,
+				      unsigned char request_val,
+				      unsigned char lanecnt);
+void exynos_dp_set_training_pattern(struct exynos_dp *dp_regs,
+				    unsigned int pattern);
+void exynos_dp_enable_enhanced_mode(struct exynos_dp *dp_regs,
+				    unsigned char enable);
+void exynos_dp_enable_scrambling(struct exynos_dp *dp_regs,
+				 unsigned int enable);
+int exynos_dp_init_video(struct exynos_dp *dp_regs);
+void exynos_dp_config_video_slave_mode(struct exynos_dp *dp_regs,
+				       struct edp_video_info *video_info);
+void exynos_dp_set_video_color_format(struct exynos_dp *dp_regs,
+				      struct edp_video_info *video_info);
+int exynos_dp_config_video_bist(struct exynos_dp *dp_regs,
+				struct exynos_dp_priv *priv);
+unsigned int exynos_dp_is_slave_video_stream_clock_on(
+					struct exynos_dp *dp_regs);
+void exynos_dp_set_video_cr_mn(struct exynos_dp *dp_regs, unsigned int type,
+			       unsigned int m_value, unsigned int n_value);
+void exynos_dp_set_video_timing_mode(struct exynos_dp *dp_regs,
+				     unsigned int type);
+void exynos_dp_enable_video_master(struct exynos_dp *dp_regs,
+				   unsigned int enable);
+void exynos_dp_start_video(struct exynos_dp *dp_regs);
+unsigned int exynos_dp_is_video_stream_on(struct exynos_dp *dp_regs);
+
+#endif /* _EXYNOS_DP_LOWLEVEL_H */
diff --git a/drivers/video/exynos/exynos_fb.c b/drivers/video/exynos/exynos_fb.c
new file mode 100644
index 0000000000000000000000000000000000000000..97228cd3cc3b27ffff1c795d6245de5bb3f7616c
--- /dev/null
+++ b/drivers/video/exynos/exynos_fb.c
@@ -0,0 +1,720 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * Author: InKi Dae <inki.dae@samsung.com>
+ * Author: Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <display.h>
+#include <div64.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <libfdt.h>
+#include <panel.h>
+#include <video.h>
+#include <video_bridge.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/mipi_dsim.h>
+#include <asm/arch/dp_info.h>
+#include <asm/arch/fb.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/system.h>
+#include <asm/gpio.h>
+#include <asm-generic/errno.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+	FIMD_RGB_INTERFACE = 1,
+	FIMD_CPU_INTERFACE = 2,
+};
+
+enum exynos_fb_rgb_mode_t {
+	MODE_RGB_P = 0,
+	MODE_BGR_P = 1,
+	MODE_RGB_S = 2,
+	MODE_BGR_S = 3,
+};
+
+struct exynos_fb_priv {
+	ushort vl_col;		/* Number of columns (i.e. 640) */
+	ushort vl_row;		/* Number of rows (i.e. 480) */
+	ushort vl_rot;		/* Rotation of Display (0, 1, 2, 3) */
+	ushort vl_width;	/* Width of display area in millimeters */
+	ushort vl_height;	/* Height of display area in millimeters */
+
+	/* LCD configuration register */
+	u_char vl_freq;		/* Frequency */
+	u_char vl_clkp;		/* Clock polarity */
+	u_char vl_oep;		/* Output Enable polarity */
+	u_char vl_hsp;		/* Horizontal Sync polarity */
+	u_char vl_vsp;		/* Vertical Sync polarity */
+	u_char vl_dp;		/* Data polarity */
+	u_char vl_bpix;		/* Bits per pixel */
+
+	/* Horizontal control register. Timing from data sheet */
+	u_char vl_hspw;		/* Horz sync pulse width */
+	u_char vl_hfpd;		/* Wait before of line */
+	u_char vl_hbpd;		/* Wait end of line */
+
+	/* Vertical control register. */
+	u_char	vl_vspw;	/* Vertical sync pulse width */
+	u_char	vl_vfpd;	/* Wait before of frame */
+	u_char	vl_vbpd;	/* Wait end of frame */
+	u_char  vl_cmd_allow_len; /* Wait end of frame */
+
+	unsigned int win_id;
+	unsigned int init_delay;
+	unsigned int power_on_delay;
+	unsigned int reset_delay;
+	unsigned int interface_mode;
+	unsigned int mipi_enabled;
+	unsigned int dp_enabled;
+	unsigned int cs_setup;
+	unsigned int wr_setup;
+	unsigned int wr_act;
+	unsigned int wr_hold;
+	unsigned int logo_on;
+	unsigned int logo_width;
+	unsigned int logo_height;
+	int logo_x_offset;
+	int logo_y_offset;
+	unsigned long logo_addr;
+	unsigned int rgb_mode;
+	unsigned int resolution;
+
+	/* parent clock name(MPLL, EPLL or VPLL) */
+	unsigned int pclk_name;
+	/* ratio value for source clock from parent clock. */
+	unsigned int sclk_div;
+
+	unsigned int dual_lcd_enabled;
+	struct exynos_fb *reg;
+	struct exynos_platform_mipi_dsim *dsim_platform_data_dt;
+};
+
+static void exynos_fimd_set_dualrgb(struct exynos_fb_priv *priv, bool enabled)
+{
+	struct exynos_fb *reg = priv->reg;
+	unsigned int cfg = 0;
+
+	if (enabled) {
+		cfg = EXYNOS_DUALRGB_BYPASS_DUAL | EXYNOS_DUALRGB_LINESPLIT |
+			EXYNOS_DUALRGB_VDEN_EN_ENABLE;
+
+		/* in case of Line Split mode, MAIN_CNT doesn't neet to set. */
+		cfg |= EXYNOS_DUALRGB_SUB_CNT(priv->vl_col / 2) |
+			EXYNOS_DUALRGB_MAIN_CNT(0);
+	}
+
+	writel(cfg, &reg->dualrgb);
+}
+
+static void exynos_fimd_set_dp_clkcon(struct exynos_fb_priv *priv,
+				      unsigned int enabled)
+{
+	struct exynos_fb *reg = priv->reg;
+	unsigned int cfg = 0;
+
+	if (enabled)
+		cfg = EXYNOS_DP_CLK_ENABLE;
+
+	writel(cfg, &reg->dp_mie_clkcon);
+}
+
+static void exynos_fimd_set_par(struct exynos_fb_priv *priv,
+				unsigned int win_id)
+{
+	struct exynos_fb *reg = priv->reg;
+	unsigned int cfg = 0;
+
+	/* set window control */
+	cfg = readl((unsigned int)&reg->wincon0 +
+			EXYNOS_WINCON(win_id));
+
+	cfg &= ~(EXYNOS_WINCON_BITSWP_ENABLE | EXYNOS_WINCON_BYTESWP_ENABLE |
+		EXYNOS_WINCON_HAWSWP_ENABLE | EXYNOS_WINCON_WSWP_ENABLE |
+		EXYNOS_WINCON_BURSTLEN_MASK | EXYNOS_WINCON_BPPMODE_MASK |
+		EXYNOS_WINCON_INRGB_MASK | EXYNOS_WINCON_DATAPATH_MASK);
+
+	/* DATAPATH is DMA */
+	cfg |= EXYNOS_WINCON_DATAPATH_DMA;
+
+	cfg |= EXYNOS_WINCON_HAWSWP_ENABLE;
+
+	/* dma burst is 16 */
+	cfg |= EXYNOS_WINCON_BURSTLEN_16WORD;
+
+	switch (priv->vl_bpix) {
+	case 4:
+		cfg |= EXYNOS_WINCON_BPPMODE_16BPP_565;
+		break;
+	default:
+		cfg |= EXYNOS_WINCON_BPPMODE_24BPP_888;
+		break;
+	}
+
+	writel(cfg, (unsigned int)&reg->wincon0 +
+			EXYNOS_WINCON(win_id));
+
+	/* set window position to x=0, y=0*/
+	cfg = EXYNOS_VIDOSD_LEFT_X(0) | EXYNOS_VIDOSD_TOP_Y(0);
+	writel(cfg, (unsigned int)&reg->vidosd0a +
+			EXYNOS_VIDOSD(win_id));
+
+	cfg = EXYNOS_VIDOSD_RIGHT_X(priv->vl_col - 1) |
+		EXYNOS_VIDOSD_BOTTOM_Y(priv->vl_row - 1) |
+		EXYNOS_VIDOSD_RIGHT_X_E(1) |
+		EXYNOS_VIDOSD_BOTTOM_Y_E(0);
+
+	writel(cfg, (unsigned int)&reg->vidosd0b +
+			EXYNOS_VIDOSD(win_id));
+
+	/* set window size for window0*/
+	cfg = EXYNOS_VIDOSD_SIZE(priv->vl_col * priv->vl_row);
+	writel(cfg, (unsigned int)&reg->vidosd0c +
+			EXYNOS_VIDOSD(win_id));
+}
+
+static void exynos_fimd_set_buffer_address(struct exynos_fb_priv *priv,
+					   unsigned int win_id,
+					   ulong lcd_base_addr)
+{
+	struct exynos_fb *reg = priv->reg;
+	unsigned long start_addr, end_addr;
+
+	start_addr = lcd_base_addr;
+	end_addr = start_addr + ((priv->vl_col * (VNBITS(priv->vl_bpix) / 8)) *
+				priv->vl_row);
+
+	writel(start_addr, (unsigned int)&reg->vidw00add0b0 +
+			EXYNOS_BUFFER_OFFSET(win_id));
+	writel(end_addr, (unsigned int)&reg->vidw00add1b0 +
+			EXYNOS_BUFFER_OFFSET(win_id));
+}
+
+static void exynos_fimd_set_clock(struct exynos_fb_priv *priv)
+{
+	struct exynos_fb *reg = priv->reg;
+	unsigned int cfg = 0, div = 0, remainder, remainder_div;
+	unsigned long pixel_clock;
+	unsigned long long src_clock;
+
+	if (priv->dual_lcd_enabled) {
+		pixel_clock = priv->vl_freq *
+				(priv->vl_hspw + priv->vl_hfpd +
+				 priv->vl_hbpd + priv->vl_col / 2) *
+				(priv->vl_vspw + priv->vl_vfpd +
+				 priv->vl_vbpd + priv->vl_row);
+	} else if (priv->interface_mode == FIMD_CPU_INTERFACE) {
+		pixel_clock = priv->vl_freq *
+				priv->vl_width * priv->vl_height *
+				(priv->cs_setup + priv->wr_setup +
+				 priv->wr_act + priv->wr_hold + 1);
+	} else {
+		pixel_clock = priv->vl_freq *
+				(priv->vl_hspw + priv->vl_hfpd +
+				 priv->vl_hbpd + priv->vl_col) *
+				(priv->vl_vspw + priv->vl_vfpd +
+				 priv->vl_vbpd + priv->vl_row);
+	}
+
+	cfg = readl(&reg->vidcon0);
+	cfg &= ~(EXYNOS_VIDCON0_CLKSEL_MASK | EXYNOS_VIDCON0_CLKVALUP_MASK |
+		EXYNOS_VIDCON0_CLKVAL_F(0xFF) | EXYNOS_VIDCON0_VCLKEN_MASK |
+		EXYNOS_VIDCON0_CLKDIR_MASK);
+	cfg |= (EXYNOS_VIDCON0_CLKSEL_SCLK | EXYNOS_VIDCON0_CLKVALUP_ALWAYS |
+		EXYNOS_VIDCON0_VCLKEN_NORMAL | EXYNOS_VIDCON0_CLKDIR_DIVIDED);
+
+	src_clock = (unsigned long long) get_lcd_clk();
+
+	/* get quotient and remainder. */
+	remainder = do_div(src_clock, pixel_clock);
+	div = src_clock;
+
+	remainder *= 10;
+	remainder_div = remainder / pixel_clock;
+
+	/* round about one places of decimals. */
+	if (remainder_div >= 5)
+		div++;
+
+	/* in case of dual lcd mode. */
+	if (priv->dual_lcd_enabled)
+		div--;
+
+	cfg |= EXYNOS_VIDCON0_CLKVAL_F(div - 1);
+	writel(cfg, &reg->vidcon0);
+}
+
+void exynos_set_trigger(struct exynos_fb_priv *priv)
+{
+	struct exynos_fb *reg = priv->reg;
+	unsigned int cfg = 0;
+
+	cfg = readl(&reg->trigcon);
+
+	cfg |= (EXYNOS_I80SOFT_TRIG_EN | EXYNOS_I80START_TRIG);
+
+	writel(cfg, &reg->trigcon);
+}
+
+int exynos_is_i80_frame_done(struct exynos_fb_priv *priv)
+{
+	struct exynos_fb *reg = priv->reg;
+	unsigned int cfg = 0;
+	int status;
+
+	cfg = readl(&reg->trigcon);
+
+	/* frame done func is valid only when TRIMODE[0] is set to 1. */
+	status = (cfg & EXYNOS_I80STATUS_TRIG_DONE) ==
+			EXYNOS_I80STATUS_TRIG_DONE;
+
+	return status;
+}
+
+static void exynos_fimd_lcd_on(struct exynos_fb_priv *priv)
+{
+	struct exynos_fb *reg = priv->reg;
+	unsigned int cfg = 0;
+
+	/* display on */
+	cfg = readl(&reg->vidcon0);
+	cfg |= (EXYNOS_VIDCON0_ENVID_ENABLE | EXYNOS_VIDCON0_ENVID_F_ENABLE);
+	writel(cfg, &reg->vidcon0);
+}
+
+static void exynos_fimd_window_on(struct exynos_fb_priv *priv,
+				  unsigned int win_id)
+{
+	struct exynos_fb *reg = priv->reg;
+	unsigned int cfg = 0;
+
+	/* enable window */
+	cfg = readl((unsigned int)&reg->wincon0 +
+			EXYNOS_WINCON(win_id));
+	cfg |= EXYNOS_WINCON_ENWIN_ENABLE;
+	writel(cfg, (unsigned int)&reg->wincon0 +
+			EXYNOS_WINCON(win_id));
+
+	cfg = readl(&reg->winshmap);
+	cfg |= EXYNOS_WINSHMAP_CH_ENABLE(win_id);
+	writel(cfg, &reg->winshmap);
+}
+
+void exynos_fimd_lcd_off(struct exynos_fb_priv *priv)
+{
+	struct exynos_fb *reg = priv->reg;
+	unsigned int cfg = 0;
+
+	cfg = readl(&reg->vidcon0);
+	cfg &= (EXYNOS_VIDCON0_ENVID_DISABLE | EXYNOS_VIDCON0_ENVID_F_DISABLE);
+	writel(cfg, &reg->vidcon0);
+}
+
+void exynos_fimd_window_off(struct exynos_fb_priv *priv, unsigned int win_id)
+{
+	struct exynos_fb *reg = priv->reg;
+	unsigned int cfg = 0;
+
+	cfg = readl((unsigned int)&reg->wincon0 +
+			EXYNOS_WINCON(win_id));
+	cfg &= EXYNOS_WINCON_ENWIN_DISABLE;
+	writel(cfg, (unsigned int)&reg->wincon0 +
+			EXYNOS_WINCON(win_id));
+
+	cfg = readl(&reg->winshmap);
+	cfg &= ~EXYNOS_WINSHMAP_CH_DISABLE(win_id);
+	writel(cfg, &reg->winshmap);
+}
+
+/*
+* The reset value for FIMD SYSMMU register MMU_CTRL is 3
+* on Exynos5420 and newer versions.
+* This means FIMD SYSMMU is on by default on Exynos5420
+* and newer versions.
+* Since in u-boot we don't use SYSMMU, we should disable
+* those FIMD SYSMMU.
+* Note that there are 2 SYSMMU for FIMD: m0 and m1.
+* m0 handles windows 0 and 4, and m1 handles windows 1, 2 and 3.
+* We disable both of them here.
+*/
+void exynos_fimd_disable_sysmmu(void)
+{
+	u32 *sysmmufimd;
+	unsigned int node;
+	int node_list[2];
+	int count;
+	int i;
+
+	count = fdtdec_find_aliases_for_id(gd->fdt_blob, "fimd",
+				COMPAT_SAMSUNG_EXYNOS_SYSMMU, node_list, 2);
+	for (i = 0; i < count; i++) {
+		node = node_list[i];
+		if (node <= 0) {
+			debug("Can't get device node for fimd sysmmu\n");
+			return;
+		}
+
+		sysmmufimd = (u32 *)fdtdec_get_addr(gd->fdt_blob, node, "reg");
+		if (!sysmmufimd) {
+			debug("Can't get base address for sysmmu fimdm0");
+			return;
+		}
+
+		writel(0x0, sysmmufimd);
+	}
+}
+
+void exynos_fimd_lcd_init(struct udevice *dev)
+{
+	struct exynos_fb_priv *priv = dev_get_priv(dev);
+	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+	struct exynos_fb *reg = priv->reg;
+	unsigned int cfg = 0, rgb_mode;
+	unsigned int offset;
+	unsigned int node;
+
+	node = dev->of_offset;
+	if (fdtdec_get_bool(gd->fdt_blob, node, "samsung,disable-sysmmu"))
+		exynos_fimd_disable_sysmmu();
+
+	offset = exynos_fimd_get_base_offset();
+
+	rgb_mode = priv->rgb_mode;
+
+	if (priv->interface_mode == FIMD_RGB_INTERFACE) {
+		cfg |= EXYNOS_VIDCON0_VIDOUT_RGB;
+		writel(cfg, &reg->vidcon0);
+
+		cfg = readl(&reg->vidcon2);
+		cfg &= ~(EXYNOS_VIDCON2_WB_MASK |
+			EXYNOS_VIDCON2_TVFORMATSEL_MASK |
+			EXYNOS_VIDCON2_TVFORMATSEL_YUV_MASK);
+		cfg |= EXYNOS_VIDCON2_WB_DISABLE;
+		writel(cfg, &reg->vidcon2);
+
+		/* set polarity */
+		cfg = 0;
+		if (!priv->vl_clkp)
+			cfg |= EXYNOS_VIDCON1_IVCLK_RISING_EDGE;
+		if (!priv->vl_hsp)
+			cfg |= EXYNOS_VIDCON1_IHSYNC_INVERT;
+		if (!priv->vl_vsp)
+			cfg |= EXYNOS_VIDCON1_IVSYNC_INVERT;
+		if (!priv->vl_dp)
+			cfg |= EXYNOS_VIDCON1_IVDEN_INVERT;
+
+		writel(cfg, (unsigned int)&reg->vidcon1 + offset);
+
+		/* set timing */
+		cfg = EXYNOS_VIDTCON0_VFPD(priv->vl_vfpd - 1);
+		cfg |= EXYNOS_VIDTCON0_VBPD(priv->vl_vbpd - 1);
+		cfg |= EXYNOS_VIDTCON0_VSPW(priv->vl_vspw - 1);
+		writel(cfg, (unsigned int)&reg->vidtcon0 + offset);
+
+		cfg = EXYNOS_VIDTCON1_HFPD(priv->vl_hfpd - 1);
+		cfg |= EXYNOS_VIDTCON1_HBPD(priv->vl_hbpd - 1);
+		cfg |= EXYNOS_VIDTCON1_HSPW(priv->vl_hspw - 1);
+
+		writel(cfg, (unsigned int)&reg->vidtcon1 + offset);
+
+		/* set lcd size */
+		cfg = EXYNOS_VIDTCON2_HOZVAL(priv->vl_col - 1) |
+			EXYNOS_VIDTCON2_LINEVAL(priv->vl_row - 1) |
+			EXYNOS_VIDTCON2_HOZVAL_E(priv->vl_col - 1) |
+			EXYNOS_VIDTCON2_LINEVAL_E(priv->vl_row - 1);
+
+		writel(cfg, (unsigned int)&reg->vidtcon2 + offset);
+	}
+
+	/* set display mode */
+	cfg = readl(&reg->vidcon0);
+	cfg &= ~EXYNOS_VIDCON0_PNRMODE_MASK;
+	cfg |= (rgb_mode << EXYNOS_VIDCON0_PNRMODE_SHIFT);
+	writel(cfg, &reg->vidcon0);
+
+	/* set par */
+	exynos_fimd_set_par(priv, priv->win_id);
+
+	/* set memory address */
+	exynos_fimd_set_buffer_address(priv, priv->win_id, plat->base);
+
+	/* set buffer size */
+	cfg = EXYNOS_VIDADDR_PAGEWIDTH(priv->vl_col *
+			VNBITS(priv->vl_bpix) / 8) |
+		EXYNOS_VIDADDR_PAGEWIDTH_E(priv->vl_col *
+			VNBITS(priv->vl_bpix) / 8) |
+		EXYNOS_VIDADDR_OFFSIZE(0) |
+		EXYNOS_VIDADDR_OFFSIZE_E(0);
+
+	writel(cfg, (unsigned int)&reg->vidw00add2 +
+					EXYNOS_BUFFER_SIZE(priv->win_id));
+
+	/* set clock */
+	exynos_fimd_set_clock(priv);
+
+	/* set rgb mode to dual lcd. */
+	exynos_fimd_set_dualrgb(priv, priv->dual_lcd_enabled);
+
+	/* display on */
+	exynos_fimd_lcd_on(priv);
+
+	/* window on */
+	exynos_fimd_window_on(priv, priv->win_id);
+
+	exynos_fimd_set_dp_clkcon(priv, priv->dp_enabled);
+}
+
+unsigned long exynos_fimd_calc_fbsize(struct exynos_fb_priv *priv)
+{
+	return priv->vl_col * priv->vl_row * (VNBITS(priv->vl_bpix) / 8);
+}
+
+int exynos_fb_ofdata_to_platdata(struct udevice *dev)
+{
+	struct exynos_fb_priv *priv = dev_get_priv(dev);
+	unsigned int node = dev->of_offset;
+	const void *blob = gd->fdt_blob;
+	fdt_addr_t addr;
+
+	addr = dev_get_addr(dev);
+	if (addr == FDT_ADDR_T_NONE) {
+		debug("Can't get the FIMD base address\n");
+		return -EINVAL;
+	}
+	priv->reg = (struct exynos_fb *)addr;
+
+	priv->vl_col = fdtdec_get_int(blob, node, "samsung,vl-col", 0);
+	if (priv->vl_col == 0) {
+		debug("Can't get XRES\n");
+		return -ENXIO;
+	}
+
+	priv->vl_row = fdtdec_get_int(blob, node, "samsung,vl-row", 0);
+	if (priv->vl_row == 0) {
+		debug("Can't get YRES\n");
+		return -ENXIO;
+	}
+
+	priv->vl_width = fdtdec_get_int(blob, node,
+						"samsung,vl-width", 0);
+
+	priv->vl_height = fdtdec_get_int(blob, node,
+						"samsung,vl-height", 0);
+
+	priv->vl_freq = fdtdec_get_int(blob, node, "samsung,vl-freq", 0);
+	if (priv->vl_freq == 0) {
+		debug("Can't get refresh rate\n");
+		return -ENXIO;
+	}
+
+	if (fdtdec_get_bool(blob, node, "samsung,vl-clkp"))
+		priv->vl_clkp = VIDEO_ACTIVE_LOW;
+
+	if (fdtdec_get_bool(blob, node, "samsung,vl-oep"))
+		priv->vl_oep = VIDEO_ACTIVE_LOW;
+
+	if (fdtdec_get_bool(blob, node, "samsung,vl-hsp"))
+		priv->vl_hsp = VIDEO_ACTIVE_LOW;
+
+	if (fdtdec_get_bool(blob, node, "samsung,vl-vsp"))
+		priv->vl_vsp = VIDEO_ACTIVE_LOW;
+
+	if (fdtdec_get_bool(blob, node, "samsung,vl-dp"))
+		priv->vl_dp = VIDEO_ACTIVE_LOW;
+
+	priv->vl_bpix = fdtdec_get_int(blob, node, "samsung,vl-bpix", 0);
+	if (priv->vl_bpix == 0) {
+		debug("Can't get bits per pixel\n");
+		return -ENXIO;
+	}
+
+	priv->vl_hspw = fdtdec_get_int(blob, node, "samsung,vl-hspw", 0);
+	if (priv->vl_hspw == 0) {
+		debug("Can't get hsync width\n");
+		return -ENXIO;
+	}
+
+	priv->vl_hfpd = fdtdec_get_int(blob, node, "samsung,vl-hfpd", 0);
+	if (priv->vl_hfpd == 0) {
+		debug("Can't get right margin\n");
+		return -ENXIO;
+	}
+
+	priv->vl_hbpd = (u_char)fdtdec_get_int(blob, node,
+							"samsung,vl-hbpd", 0);
+	if (priv->vl_hbpd == 0) {
+		debug("Can't get left margin\n");
+		return -ENXIO;
+	}
+
+	priv->vl_vspw = (u_char)fdtdec_get_int(blob, node,
+							"samsung,vl-vspw", 0);
+	if (priv->vl_vspw == 0) {
+		debug("Can't get vsync width\n");
+		return -ENXIO;
+	}
+
+	priv->vl_vfpd = fdtdec_get_int(blob, node,
+							"samsung,vl-vfpd", 0);
+	if (priv->vl_vfpd == 0) {
+		debug("Can't get lower margin\n");
+		return -ENXIO;
+	}
+
+	priv->vl_vbpd = fdtdec_get_int(blob, node, "samsung,vl-vbpd", 0);
+	if (priv->vl_vbpd == 0) {
+		debug("Can't get upper margin\n");
+		return -ENXIO;
+	}
+
+	priv->vl_cmd_allow_len = fdtdec_get_int(blob, node,
+						"samsung,vl-cmd-allow-len", 0);
+
+	priv->win_id = fdtdec_get_int(blob, node, "samsung,winid", 0);
+	priv->init_delay = fdtdec_get_int(blob, node,
+						"samsung,init-delay", 0);
+	priv->power_on_delay = fdtdec_get_int(blob, node,
+						"samsung,power-on-delay", 0);
+	priv->reset_delay = fdtdec_get_int(blob, node,
+						"samsung,reset-delay", 0);
+	priv->interface_mode = fdtdec_get_int(blob, node,
+						"samsung,interface-mode", 0);
+	priv->mipi_enabled = fdtdec_get_int(blob, node,
+						"samsung,mipi-enabled", 0);
+	priv->dp_enabled = fdtdec_get_int(blob, node,
+						"samsung,dp-enabled", 0);
+	priv->cs_setup = fdtdec_get_int(blob, node,
+						"samsung,cs-setup", 0);
+	priv->wr_setup = fdtdec_get_int(blob, node,
+						"samsung,wr-setup", 0);
+	priv->wr_act = fdtdec_get_int(blob, node, "samsung,wr-act", 0);
+	priv->wr_hold = fdtdec_get_int(blob, node, "samsung,wr-hold", 0);
+
+	priv->logo_on = fdtdec_get_int(blob, node, "samsung,logo-on", 0);
+	if (priv->logo_on) {
+		priv->logo_width = fdtdec_get_int(blob, node,
+						"samsung,logo-width", 0);
+		priv->logo_height = fdtdec_get_int(blob, node,
+						"samsung,logo-height", 0);
+		priv->logo_addr = fdtdec_get_int(blob, node,
+						"samsung,logo-addr", 0);
+	}
+
+	priv->rgb_mode = fdtdec_get_int(blob, node,
+						"samsung,rgb-mode", 0);
+	priv->pclk_name = fdtdec_get_int(blob, node,
+						"samsung,pclk-name", 0);
+	priv->sclk_div = fdtdec_get_int(blob, node,
+						"samsung,sclk-div", 0);
+	priv->dual_lcd_enabled = fdtdec_get_int(blob, node,
+						"samsung,dual-lcd-enabled", 0);
+
+	return 0;
+}
+
+static int exynos_fb_probe(struct udevice *dev)
+{
+	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct exynos_fb_priv *priv = dev_get_priv(dev);
+	struct udevice *panel, *bridge;
+	struct udevice *dp;
+	int ret;
+
+	debug("%s: start\n", __func__);
+	set_system_display_ctrl();
+	set_lcd_clk();
+
+#ifdef CONFIG_EXYNOS_MIPI_DSIM
+	exynos_init_dsim_platform_data(&panel_info);
+#endif
+	exynos_fimd_lcd_init(dev);
+
+	ret = uclass_first_device(UCLASS_PANEL, &panel);
+	if (ret) {
+		printf("LCD panel failed to probe\n");
+		return ret;
+	}
+	if (!panel) {
+		printf("LCD panel not found\n");
+		return -ENODEV;
+	}
+
+	ret = uclass_first_device(UCLASS_DISPLAY, &dp);
+	if (ret) {
+		debug("%s: Display device error %d\n", __func__, ret);
+		return ret;
+	}
+	if (!dev) {
+		debug("%s: Display device missing\n", __func__);
+		return -ENODEV;
+	}
+	ret = display_enable(dp, 18, NULL);
+	if (ret) {
+		debug("%s: Display enable error %d\n", __func__, ret);
+		return ret;
+	}
+
+	/* backlight / pwm */
+	ret = panel_enable_backlight(panel);
+	if (ret) {
+		debug("%s: backlight error: %d\n", __func__, ret);
+		return ret;
+	}
+
+	ret = uclass_get_device(UCLASS_VIDEO_BRIDGE, 0, &bridge);
+	if (!ret)
+		ret = video_bridge_set_backlight(bridge, 80);
+	if (ret) {
+		debug("%s: No video bridge, or no backlight on bridge\n",
+		      __func__);
+		exynos_pinmux_config(PERIPH_ID_PWM0, 0);
+	}
+
+	uc_priv->xsize = priv->vl_col;
+	uc_priv->ysize = priv->vl_row;
+	uc_priv->bpix = priv->vl_bpix;
+
+	/* Enable flushing after LCD writes if requested */
+	video_set_flush_dcache(dev, true);
+
+	return 0;
+}
+
+static int exynos_fb_bind(struct udevice *dev)
+{
+	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
+
+	/* This is the maximum panel size we expect to see */
+	plat->size = 1920 * 1080 * 2;
+
+	return 0;
+}
+
+static const struct video_ops exynos_fb_ops = {
+};
+
+static const struct udevice_id exynos_fb_ids[] = {
+	{ .compatible = "samsung,exynos-fimd" },
+	{ }
+};
+
+U_BOOT_DRIVER(exynos_fb) = {
+	.name	= "exynos_fb",
+	.id	= UCLASS_VIDEO,
+	.of_match = exynos_fb_ids,
+	.ops	= &exynos_fb_ops,
+	.bind	= exynos_fb_bind,
+	.probe	= exynos_fb_probe,
+	.ofdata_to_platdata	= exynos_fb_ofdata_to_platdata,
+	.priv_auto_alloc_size	= sizeof(struct exynos_fb_priv),
+};
diff --git a/drivers/video/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
similarity index 80%
rename from drivers/video/exynos_mipi_dsi.c
rename to drivers/video/exynos/exynos_mipi_dsi.c
index b597accf3d81f9380fb303e11ec2f8832676244f..a5d9b5921868c00bf32543ac493f601be6398ec5 100644
--- a/drivers/video/exynos_mipi_dsi.c
+++ b/drivers/video/exynos/exynos_mipi_dsi.c
@@ -27,13 +27,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static struct exynos_platform_mipi_dsim *dsim_pd;
-#if CONFIG_IS_ENABLED(OF_CONTROL)
-static struct mipi_dsim_config dsim_config_dt;
-static struct exynos_platform_mipi_dsim dsim_platform_data_dt;
-static struct mipi_dsim_lcd_device mipi_lcd_device_dt;
-#endif
-
 struct mipi_dsim_ddi {
 	int				bus_id;
 	struct list_head		list;
@@ -178,7 +171,7 @@ static struct mipi_dsim_master_ops master_ops = {
 	.clear_dsim_frame_done		= exynos_mipi_dsi_clear_frame_done,
 };
 
-int exynos_mipi_dsi_init(void)
+int exynos_mipi_dsi_init(struct exynos_platform_mipi_dsim *dsim_pd)
 {
 	struct mipi_dsim_device *dsim;
 	struct mipi_dsim_config *dsim_config;
@@ -239,18 +232,8 @@ int exynos_mipi_dsi_init(void)
 	return 0;
 }
 
-void exynos_set_dsim_platform_data(struct exynos_platform_mipi_dsim *pd)
-{
-	if (pd == NULL) {
-		debug("pd is NULL\n");
-		return;
-	}
-
-	dsim_pd = pd;
-}
-
-#if CONFIG_IS_ENABLED(OF_CONTROL)
-int exynos_dsim_config_parse_dt(const void *blob)
+int exynos_dsim_config_parse_dt(const void *blob, struct mipi_dsim_config *dt,
+				struct mipi_dsim_lcd_device *lcd_dt)
 {
 	int node;
 
@@ -260,59 +243,59 @@ int exynos_dsim_config_parse_dt(const void *blob)
 		return -ENODEV;
 	}
 
-	dsim_config_dt.e_interface = fdtdec_get_int(blob, node,
+	dt->e_interface = fdtdec_get_int(blob, node,
 				"samsung,dsim-config-e-interface", 0);
 
-	dsim_config_dt.e_virtual_ch = fdtdec_get_int(blob, node,
+	dt->e_virtual_ch = fdtdec_get_int(blob, node,
 				"samsung,dsim-config-e-virtual-ch", 0);
 
-	dsim_config_dt.e_pixel_format = fdtdec_get_int(blob, node,
+	dt->e_pixel_format = fdtdec_get_int(blob, node,
 				"samsung,dsim-config-e-pixel-format", 0);
 
-	dsim_config_dt.e_burst_mode = fdtdec_get_int(blob, node,
+	dt->e_burst_mode = fdtdec_get_int(blob, node,
 				"samsung,dsim-config-e-burst-mode", 0);
 
-	dsim_config_dt.e_no_data_lane = fdtdec_get_int(blob, node,
+	dt->e_no_data_lane = fdtdec_get_int(blob, node,
 				"samsung,dsim-config-e-no-data-lane", 0);
 
-	dsim_config_dt.e_byte_clk = fdtdec_get_int(blob, node,
+	dt->e_byte_clk = fdtdec_get_int(blob, node,
 				"samsung,dsim-config-e-byte-clk", 0);
 
-	dsim_config_dt.hfp = fdtdec_get_int(blob, node,
+	dt->hfp = fdtdec_get_int(blob, node,
 				"samsung,dsim-config-hfp", 0);
 
-	dsim_config_dt.p = fdtdec_get_int(blob, node,
+	dt->p = fdtdec_get_int(blob, node,
 					  "samsung,dsim-config-p", 0);
-	dsim_config_dt.m = fdtdec_get_int(blob, node,
+	dt->m = fdtdec_get_int(blob, node,
 					  "samsung,dsim-config-m", 0);
-	dsim_config_dt.s = fdtdec_get_int(blob, node,
+	dt->s = fdtdec_get_int(blob, node,
 					  "samsung,dsim-config-s", 0);
 
-	dsim_config_dt.pll_stable_time = fdtdec_get_int(blob, node,
+	dt->pll_stable_time = fdtdec_get_int(blob, node,
 				"samsung,dsim-config-pll-stable-time", 0);
 
-	dsim_config_dt.esc_clk = fdtdec_get_int(blob, node,
+	dt->esc_clk = fdtdec_get_int(blob, node,
 				"samsung,dsim-config-esc-clk", 0);
 
-	dsim_config_dt.stop_holding_cnt = fdtdec_get_int(blob, node,
+	dt->stop_holding_cnt = fdtdec_get_int(blob, node,
 				"samsung,dsim-config-stop-holding-cnt", 0);
 
-	dsim_config_dt.bta_timeout = fdtdec_get_int(blob, node,
+	dt->bta_timeout = fdtdec_get_int(blob, node,
 				"samsung,dsim-config-bta-timeout", 0);
 
-	dsim_config_dt.rx_timeout = fdtdec_get_int(blob, node,
+	dt->rx_timeout = fdtdec_get_int(blob, node,
 				"samsung,dsim-config-rx-timeout", 0);
 
-	mipi_lcd_device_dt.name = fdtdec_get_config_string(blob,
+	lcd_dt->name = fdtdec_get_config_string(blob,
 				"samsung,dsim-device-name");
 
-	mipi_lcd_device_dt.id = fdtdec_get_int(blob, node,
+	lcd_dt->id = fdtdec_get_int(blob, node,
 				"samsung,dsim-device-id", 0);
 
-	mipi_lcd_device_dt.bus_id = fdtdec_get_int(blob, node,
+	lcd_dt->bus_id = fdtdec_get_int(blob, node,
 				"samsung,dsim-device-bus_id", 0);
 
-	mipi_lcd_device_dt.reverse_panel = fdtdec_get_int(blob, node,
+	lcd_dt->reverse_panel = fdtdec_get_int(blob, node,
 				"samsung,dsim-device-reverse-panel", 0);
 
 	return 0;
@@ -320,7 +303,12 @@ int exynos_dsim_config_parse_dt(const void *blob)
 
 void exynos_init_dsim_platform_data(vidinfo_t *vid)
 {
-	if (exynos_dsim_config_parse_dt(gd->fdt_blob))
+	static struct mipi_dsim_config dsim_config_dt;
+	static struct exynos_platform_mipi_dsim dsim_platform_data_dt;
+	static struct mipi_dsim_lcd_device mipi_lcd_device_dt;
+
+	if (exynos_dsim_config_parse_dt(gd->fdt_blob, &dsim_config_dt,
+					&mipi_lcd_device_dt))
 		debug("Can't get proper dsim config.\n");
 
 	strcpy(dsim_platform_data_dt.lcd_panel_name, mipi_lcd_device_dt.name);
@@ -332,6 +320,5 @@ void exynos_init_dsim_platform_data(vidinfo_t *vid)
 	mipi_lcd_device_dt.platform_data = (void *)&dsim_platform_data_dt;
 	exynos_mipi_dsi_register_lcd_device(&mipi_lcd_device_dt);
 
-	dsim_pd = &dsim_platform_data_dt;
+	vid->dsim_platform_data_dt = &dsim_platform_data_dt;
 }
-#endif
diff --git a/drivers/video/exynos_mipi_dsi_common.c b/drivers/video/exynos/exynos_mipi_dsi_common.c
similarity index 99%
rename from drivers/video/exynos_mipi_dsi_common.c
rename to drivers/video/exynos/exynos_mipi_dsi_common.c
index 925d51500a5a500e948f0e45be97a0e820d35909..85c5e0de933198bf06a07c416e4edcd68a7b85d0 100644
--- a/drivers/video/exynos_mipi_dsi_common.c
+++ b/drivers/video/exynos/exynos_mipi_dsi_common.c
@@ -465,7 +465,7 @@ int exynos_mipi_dsi_enable_frame_done_int(struct mipi_dsim_device *dsim,
 }
 
 static void convert_to_fb_videomode(struct fb_videomode *mode1,
-				vidinfo_t *mode2)
+				    struct vidinfo *mode2)
 {
 	mode1->xres = mode2->vl_width;
 	mode1->yres = mode2->vl_height;
@@ -482,10 +482,10 @@ int exynos_mipi_dsi_set_display_mode(struct mipi_dsim_device *dsim,
 {
 	struct exynos_platform_mipi_dsim *dsim_pd;
 	struct fb_videomode lcd_video;
-	vidinfo_t *vid;
+	struct vidinfo *vid;
 
 	dsim_pd = (struct exynos_platform_mipi_dsim *)dsim->pd;
-	vid = (vidinfo_t *)dsim_pd->lcd_panel_info;
+	vid = (struct vidinfo *)dsim_pd->lcd_panel_info;
 
 	convert_to_fb_videomode(&lcd_video, vid);
 
diff --git a/drivers/video/exynos_mipi_dsi_common.h b/drivers/video/exynos/exynos_mipi_dsi_common.h
similarity index 100%
rename from drivers/video/exynos_mipi_dsi_common.h
rename to drivers/video/exynos/exynos_mipi_dsi_common.h
diff --git a/drivers/video/exynos_mipi_dsi_lowlevel.c b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
similarity index 100%
rename from drivers/video/exynos_mipi_dsi_lowlevel.c
rename to drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
diff --git a/drivers/video/exynos_mipi_dsi_lowlevel.h b/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h
similarity index 100%
rename from drivers/video/exynos_mipi_dsi_lowlevel.h
rename to drivers/video/exynos/exynos_mipi_dsi_lowlevel.h
diff --git a/drivers/video/exynos_pwm_bl.c b/drivers/video/exynos/exynos_pwm_bl.c
similarity index 100%
rename from drivers/video/exynos_pwm_bl.c
rename to drivers/video/exynos/exynos_pwm_bl.c
diff --git a/drivers/video/exynos_dp_lowlevel.h b/drivers/video/exynos_dp_lowlevel.h
deleted file mode 100644
index 86516815204f0c70cb628e818f9ced165ea2c703..0000000000000000000000000000000000000000
--- a/drivers/video/exynos_dp_lowlevel.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2012 Samsung Electronics
- *
- * Author: Donghwa Lee <dh09.lee@samsung.com>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#ifndef _EXYNOS_EDP_LOWLEVEL_H
-#define _EXYNOS_EDP_LOWLEVEL_H
-
-void exynos_dp_enable_video_bist(unsigned int enable);
-void exynos_dp_enable_video_mute(unsigned int enable);
-void exynos_dp_reset(void);
-void exynos_dp_enable_sw_func(unsigned int enable);
-unsigned int exynos_dp_set_analog_power_down(unsigned int block, u32 enable);
-unsigned int exynos_dp_get_pll_lock_status(void);
-int exynos_dp_init_analog_func(void);
-void exynos_dp_init_hpd(void);
-void exynos_dp_init_aux(void);
-void exynos_dp_config_interrupt(void);
-unsigned int exynos_dp_get_plug_in_status(void);
-unsigned int exynos_dp_detect_hpd(void);
-unsigned int exynos_dp_start_aux_transaction(void);
-unsigned int exynos_dp_write_byte_to_dpcd(unsigned int reg_addr,
-				unsigned char data);
-unsigned int exynos_dp_read_byte_from_dpcd(unsigned int reg_addr,
-		unsigned char *data);
-unsigned int exynos_dp_write_bytes_to_dpcd(unsigned int reg_addr,
-		unsigned int count,
-		unsigned char data[]);
-unsigned int exynos_dp_read_bytes_from_dpcd( unsigned int reg_addr,
-		unsigned int count,
-		unsigned char data[]);
-int exynos_dp_select_i2c_device( unsigned int device_addr,
-		unsigned int reg_addr);
-int exynos_dp_read_byte_from_i2c(unsigned int device_addr,
-		unsigned int reg_addr, unsigned int *data);
-int exynos_dp_read_bytes_from_i2c(unsigned int device_addr,
-		unsigned int reg_addr, unsigned int count,
-		unsigned char edid[]);
-void exynos_dp_reset_macro(void);
-void exynos_dp_set_link_bandwidth(unsigned char bwtype);
-unsigned char exynos_dp_get_link_bandwidth(void);
-void exynos_dp_set_lane_count(unsigned char count);
-unsigned int exynos_dp_get_lane_count(void);
-unsigned char exynos_dp_get_lanex_pre_emphasis(unsigned char lanecnt);
-void exynos_dp_set_lane_pre_emphasis(unsigned int level,
-		unsigned char lanecnt);
-void exynos_dp_set_lanex_pre_emphasis(unsigned char request_val,
-		unsigned char lanecnt);
-void exynos_dp_set_training_pattern(unsigned int pattern);
-void exynos_dp_enable_enhanced_mode(unsigned char enable);
-void exynos_dp_enable_scrambling(unsigned int enable);
-int exynos_dp_init_video(void);
-void exynos_dp_config_video_slave_mode(struct edp_video_info *video_info);
-void exynos_dp_set_video_color_format(struct edp_video_info *video_info);
-int exynos_dp_config_video_bist(struct edp_device_info *edp_info);
-unsigned int exynos_dp_is_slave_video_stream_clock_on(void);
-void exynos_dp_set_video_cr_mn(unsigned int type, unsigned int m_value,
-		unsigned int n_value);
-void exynos_dp_set_video_timing_mode(unsigned int type);
-void exynos_dp_enable_video_master(unsigned int enable);
-void exynos_dp_start_video(void);
-unsigned int exynos_dp_is_video_stream_on(void);
-void exynos_dp_set_base_addr(void);
-
-#endif /* _EXYNOS_DP_LOWLEVEL_H */
diff --git a/drivers/video/exynos_fb.c b/drivers/video/exynos_fb.c
deleted file mode 100644
index 69edc3a3a4a382512167ae3660f49f953c419be5..0000000000000000000000000000000000000000
--- a/drivers/video/exynos_fb.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * Copyright (C) 2012 Samsung Electronics
- *
- * Author: InKi Dae <inki.dae@samsung.com>
- * Author: Donghwa Lee <dh09.lee@samsung.com>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <config.h>
-#include <common.h>
-#include <lcd.h>
-#include <fdtdec.h>
-#include <libfdt.h>
-#include <asm/io.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/clk.h>
-#include <asm/arch/mipi_dsim.h>
-#include <asm/arch/dp_info.h>
-#include <asm/arch/system.h>
-#include <asm/gpio.h>
-#include <asm-generic/errno.h>
-
-#include "exynos_fb.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-static unsigned int panel_width, panel_height;
-
-#if CONFIG_IS_ENABLED(OF_CONTROL)
-vidinfo_t panel_info  = {
-	/*
-	 * Insert a value here so that we don't end up in the BSS
-	 * Reference: drivers/video/tegra.c
-	 */
-	.vl_col = -1,
-};
-#endif
-
-ushort *configuration_get_cmap(void)
-{
-#if defined(CONFIG_LCD_LOGO)
-	return bmp_logo_palette;
-#else
-	return NULL;
-#endif
-}
-
-static void exynos_lcd_init_mem(void *lcdbase, vidinfo_t *vid)
-{
-	unsigned long palette_size;
-	unsigned int fb_size;
-
-	fb_size = vid->vl_row * vid->vl_col * (NBITS(vid->vl_bpix) >> 3);
-
-	palette_size = NBITS(vid->vl_bpix) == 8 ? 256 : 16;
-
-	exynos_fimd_lcd_init_mem((unsigned long)lcdbase,
-			(unsigned long)fb_size, palette_size);
-}
-
-static void exynos_lcd_init(vidinfo_t *vid)
-{
-	exynos_fimd_lcd_init(vid);
-
-	/* Enable flushing after LCD writes if requested */
-	lcd_set_flush_dcache(1);
-}
-
-__weak void exynos_cfg_lcd_gpio(void)
-{
-}
-
-__weak void exynos_backlight_on(unsigned int onoff)
-{
-}
-
-__weak void exynos_reset_lcd(void)
-{
-}
-
-__weak void exynos_lcd_power_on(void)
-{
-}
-
-__weak void exynos_cfg_ldo(void)
-{
-}
-
-__weak void exynos_enable_ldo(unsigned int onoff)
-{
-}
-
-__weak void exynos_backlight_reset(void)
-{
-}
-
-__weak int exynos_lcd_misc_init(vidinfo_t *vid)
-{
-	return 0;
-}
-
-static void lcd_panel_on(vidinfo_t *vid)
-{
-	struct gpio_desc pwm_out_gpio;
-	struct gpio_desc bl_en_gpio;
-	unsigned int node;
-
-	udelay(vid->init_delay);
-
-	exynos_backlight_reset();
-
-	exynos_cfg_lcd_gpio();
-
-	exynos_lcd_power_on();
-
-	udelay(vid->power_on_delay);
-
-	if (vid->dp_enabled)
-		exynos_init_dp();
-
-	exynos_reset_lcd();
-
-	udelay(vid->reset_delay);
-
-	exynos_backlight_on(1);
-
-#if CONFIG_IS_ENABLED(OF_CONTROL)
-	node = fdtdec_next_compatible(gd->fdt_blob, 0,
-						COMPAT_SAMSUNG_EXYNOS_FIMD);
-	if (node <= 0) {
-		debug("FIMD: Can't get device node for FIMD\n");
-		return;
-	}
-	gpio_request_by_name_nodev(gd->fdt_blob, node, "samsung,pwm-out-gpio",
-				   0, &pwm_out_gpio,
-				   GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
-
-	gpio_request_by_name_nodev(gd->fdt_blob, node, "samsung,bl-en-gpio", 0,
-				   &bl_en_gpio,
-				   GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
-
-#endif
-	exynos_cfg_ldo();
-
-	exynos_enable_ldo(1);
-
-	if (vid->mipi_enabled)
-		exynos_mipi_dsi_init();
-}
-
-#if CONFIG_IS_ENABLED(OF_CONTROL)
-int exynos_lcd_early_init(const void *blob)
-{
-	unsigned int node;
-	node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS_FIMD);
-	if (node <= 0) {
-		debug("exynos_fb: Can't get device node for fimd\n");
-		return -ENODEV;
-	}
-
-	panel_info.vl_col = fdtdec_get_int(blob, node, "samsung,vl-col", 0);
-	if (panel_info.vl_col == 0) {
-		debug("Can't get XRES\n");
-		return -ENXIO;
-	}
-
-	panel_info.vl_row = fdtdec_get_int(blob, node, "samsung,vl-row", 0);
-	if (panel_info.vl_row == 0) {
-		debug("Can't get YRES\n");
-		return -ENXIO;
-	}
-
-	panel_info.vl_width = fdtdec_get_int(blob, node,
-						"samsung,vl-width", 0);
-
-	panel_info.vl_height = fdtdec_get_int(blob, node,
-						"samsung,vl-height", 0);
-
-	panel_info.vl_freq = fdtdec_get_int(blob, node, "samsung,vl-freq", 0);
-	if (panel_info.vl_freq == 0) {
-		debug("Can't get refresh rate\n");
-		return -ENXIO;
-	}
-
-	if (fdtdec_get_bool(blob, node, "samsung,vl-clkp"))
-		panel_info.vl_clkp = CONFIG_SYS_LOW;
-
-	if (fdtdec_get_bool(blob, node, "samsung,vl-oep"))
-		panel_info.vl_oep = CONFIG_SYS_LOW;
-
-	if (fdtdec_get_bool(blob, node, "samsung,vl-hsp"))
-		panel_info.vl_hsp = CONFIG_SYS_LOW;
-
-	if (fdtdec_get_bool(blob, node, "samsung,vl-vsp"))
-		panel_info.vl_vsp = CONFIG_SYS_LOW;
-
-	if (fdtdec_get_bool(blob, node, "samsung,vl-dp"))
-		panel_info.vl_dp = CONFIG_SYS_LOW;
-
-	panel_info.vl_bpix = fdtdec_get_int(blob, node, "samsung,vl-bpix", 0);
-	if (panel_info.vl_bpix == 0) {
-		debug("Can't get bits per pixel\n");
-		return -ENXIO;
-	}
-
-	panel_info.vl_hspw = fdtdec_get_int(blob, node, "samsung,vl-hspw", 0);
-	if (panel_info.vl_hspw == 0) {
-		debug("Can't get hsync width\n");
-		return -ENXIO;
-	}
-
-	panel_info.vl_hfpd = fdtdec_get_int(blob, node, "samsung,vl-hfpd", 0);
-	if (panel_info.vl_hfpd == 0) {
-		debug("Can't get right margin\n");
-		return -ENXIO;
-	}
-
-	panel_info.vl_hbpd = (u_char)fdtdec_get_int(blob, node,
-							"samsung,vl-hbpd", 0);
-	if (panel_info.vl_hbpd == 0) {
-		debug("Can't get left margin\n");
-		return -ENXIO;
-	}
-
-	panel_info.vl_vspw = (u_char)fdtdec_get_int(blob, node,
-							"samsung,vl-vspw", 0);
-	if (panel_info.vl_vspw == 0) {
-		debug("Can't get vsync width\n");
-		return -ENXIO;
-	}
-
-	panel_info.vl_vfpd = fdtdec_get_int(blob, node,
-							"samsung,vl-vfpd", 0);
-	if (panel_info.vl_vfpd == 0) {
-		debug("Can't get lower margin\n");
-		return -ENXIO;
-	}
-
-	panel_info.vl_vbpd = fdtdec_get_int(blob, node, "samsung,vl-vbpd", 0);
-	if (panel_info.vl_vbpd == 0) {
-		debug("Can't get upper margin\n");
-		return -ENXIO;
-	}
-
-	panel_info.vl_cmd_allow_len = fdtdec_get_int(blob, node,
-						"samsung,vl-cmd-allow-len", 0);
-
-	panel_info.win_id = fdtdec_get_int(blob, node, "samsung,winid", 0);
-	panel_info.init_delay = fdtdec_get_int(blob, node,
-						"samsung,init-delay", 0);
-	panel_info.power_on_delay = fdtdec_get_int(blob, node,
-						"samsung,power-on-delay", 0);
-	panel_info.reset_delay = fdtdec_get_int(blob, node,
-						"samsung,reset-delay", 0);
-	panel_info.interface_mode = fdtdec_get_int(blob, node,
-						"samsung,interface-mode", 0);
-	panel_info.mipi_enabled = fdtdec_get_int(blob, node,
-						"samsung,mipi-enabled", 0);
-	panel_info.dp_enabled = fdtdec_get_int(blob, node,
-						"samsung,dp-enabled", 0);
-	panel_info.cs_setup = fdtdec_get_int(blob, node,
-						"samsung,cs-setup", 0);
-	panel_info.wr_setup = fdtdec_get_int(blob, node,
-						"samsung,wr-setup", 0);
-	panel_info.wr_act = fdtdec_get_int(blob, node, "samsung,wr-act", 0);
-	panel_info.wr_hold = fdtdec_get_int(blob, node, "samsung,wr-hold", 0);
-
-	panel_info.logo_on = fdtdec_get_int(blob, node, "samsung,logo-on", 0);
-	if (panel_info.logo_on) {
-		panel_info.logo_width = fdtdec_get_int(blob, node,
-						"samsung,logo-width", 0);
-		panel_info.logo_height = fdtdec_get_int(blob, node,
-						"samsung,logo-height", 0);
-		panel_info.logo_addr = fdtdec_get_int(blob, node,
-						"samsung,logo-addr", 0);
-	}
-
-	panel_info.rgb_mode = fdtdec_get_int(blob, node,
-						"samsung,rgb-mode", 0);
-	panel_info.pclk_name = fdtdec_get_int(blob, node,
-						"samsung,pclk-name", 0);
-	panel_info.sclk_div = fdtdec_get_int(blob, node,
-						"samsung,sclk-div", 0);
-	panel_info.dual_lcd_enabled = fdtdec_get_int(blob, node,
-						"samsung,dual-lcd-enabled", 0);
-
-	return 0;
-}
-#endif
-
-void lcd_ctrl_init(void *lcdbase)
-{
-	set_system_display_ctrl();
-	set_lcd_clk();
-
-#if CONFIG_IS_ENABLED(OF_CONTROL)
-#ifdef CONFIG_EXYNOS_MIPI_DSIM
-	exynos_init_dsim_platform_data(&panel_info);
-#endif
-	exynos_lcd_misc_init(&panel_info);
-#else
-	/* initialize parameters which is specific to panel. */
-	init_panel_info(&panel_info);
-#endif
-
-	panel_width = panel_info.vl_width;
-	panel_height = panel_info.vl_height;
-
-	exynos_lcd_init_mem(lcdbase, &panel_info);
-
-	exynos_lcd_init(&panel_info);
-}
-
-void lcd_enable(void)
-{
-	if (panel_info.logo_on) {
-		memset((void *) gd->fb_base, 0, panel_width * panel_height *
-				(NBITS(panel_info.vl_bpix) >> 3));
-	}
-
-	lcd_panel_on(&panel_info);
-}
-
-/* dummy function */
-void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
-{
-	return;
-}
diff --git a/drivers/video/exynos_fb.h b/drivers/video/exynos_fb.h
deleted file mode 100644
index 2c2f94bd036bcfcd99632a133244420a48c4847f..0000000000000000000000000000000000000000
--- a/drivers/video/exynos_fb.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2012 Samsung Electronics
- *
- * Author: InKi Dae <inki.dae@samsung.com>
- * Author: Donghwa Lee <dh09.lee@samsung.com>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#ifndef _EXYNOS_FB_H_
-#define _EXYNOS_FB_H_
-
-#include <asm/arch/fb.h>
-
-#define MAX_CLOCK	(86 * 1000000)
-
-enum exynos_cpu_auto_cmd_rate {
-	DISABLE_AUTO_FRM,
-	PER_TWO_FRM,
-	PER_FOUR_FRM,
-	PER_SIX_FRM,
-	PER_EIGHT_FRM,
-	PER_TEN_FRM,
-	PER_TWELVE_FRM,
-	PER_FOURTEEN_FRM,
-	PER_SIXTEEN_FRM,
-	PER_EIGHTEEN_FRM,
-	PER_TWENTY_FRM,
-	PER_TWENTY_TWO_FRM,
-	PER_TWENTY_FOUR_FRM,
-	PER_TWENTY_SIX_FRM,
-	PER_TWENTY_EIGHT_FRM,
-	PER_THIRTY_FRM,
-};
-
-void exynos_fimd_lcd_init_mem(unsigned long screen_base, unsigned long fb_size,
-	unsigned long palette_size);
-void exynos_fimd_lcd_init(vidinfo_t *vid);
-unsigned long exynos_fimd_calc_fbsize(void);
-
-#endif
diff --git a/drivers/video/exynos_fimd.c b/drivers/video/exynos_fimd.c
deleted file mode 100644
index ac001a801e0917b9f56ecef86aa01c545793f557..0000000000000000000000000000000000000000
--- a/drivers/video/exynos_fimd.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Copyright (C) 2012 Samsung Electronics
- *
- * Author: InKi Dae <inki.dae@samsung.com>
- * Author: Donghwa Lee <dh09.lee@samsung.com>
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <config.h>
-#include <common.h>
-#include <asm/io.h>
-#include <lcd.h>
-#include <div64.h>
-#include <fdtdec.h>
-#include <libfdt.h>
-#include <asm/arch/clk.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/cpu.h>
-#include "exynos_fb.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-static unsigned long *lcd_base_addr;
-static vidinfo_t *pvid;
-static struct exynos_fb *fimd_ctrl;
-
-void exynos_fimd_lcd_init_mem(u_long screen_base, u_long fb_size,
-		u_long palette_size)
-{
-	lcd_base_addr = (unsigned long *)screen_base;
-}
-
-static void exynos_fimd_set_dualrgb(unsigned int enabled)
-{
-	unsigned int cfg = 0;
-
-	if (enabled) {
-		cfg = EXYNOS_DUALRGB_BYPASS_DUAL | EXYNOS_DUALRGB_LINESPLIT |
-			EXYNOS_DUALRGB_VDEN_EN_ENABLE;
-
-		/* in case of Line Split mode, MAIN_CNT doesn't neet to set. */
-		cfg |= EXYNOS_DUALRGB_SUB_CNT(pvid->vl_col / 2) |
-			EXYNOS_DUALRGB_MAIN_CNT(0);
-	}
-
-	writel(cfg, &fimd_ctrl->dualrgb);
-}
-
-static void exynos_fimd_set_dp_clkcon(unsigned int enabled)
-{
-	unsigned int cfg = 0;
-
-	if (enabled)
-		cfg = EXYNOS_DP_CLK_ENABLE;
-
-	writel(cfg, &fimd_ctrl->dp_mie_clkcon);
-}
-
-static void exynos_fimd_set_par(unsigned int win_id)
-{
-	unsigned int cfg = 0;
-
-	/* set window control */
-	cfg = readl((unsigned int)&fimd_ctrl->wincon0 +
-			EXYNOS_WINCON(win_id));
-
-	cfg &= ~(EXYNOS_WINCON_BITSWP_ENABLE | EXYNOS_WINCON_BYTESWP_ENABLE |
-		EXYNOS_WINCON_HAWSWP_ENABLE | EXYNOS_WINCON_WSWP_ENABLE |
-		EXYNOS_WINCON_BURSTLEN_MASK | EXYNOS_WINCON_BPPMODE_MASK |
-		EXYNOS_WINCON_INRGB_MASK | EXYNOS_WINCON_DATAPATH_MASK);
-
-	/* DATAPATH is DMA */
-	cfg |= EXYNOS_WINCON_DATAPATH_DMA;
-
-	cfg |= EXYNOS_WINCON_HAWSWP_ENABLE;
-
-	/* dma burst is 16 */
-	cfg |= EXYNOS_WINCON_BURSTLEN_16WORD;
-
-	switch (pvid->vl_bpix) {
-	case 4:
-		cfg |= EXYNOS_WINCON_BPPMODE_16BPP_565;
-		break;
-	default:
-		cfg |= EXYNOS_WINCON_BPPMODE_24BPP_888;
-		break;
-	}
-
-	writel(cfg, (unsigned int)&fimd_ctrl->wincon0 +
-			EXYNOS_WINCON(win_id));
-
-	/* set window position to x=0, y=0*/
-	cfg = EXYNOS_VIDOSD_LEFT_X(0) | EXYNOS_VIDOSD_TOP_Y(0);
-	writel(cfg, (unsigned int)&fimd_ctrl->vidosd0a +
-			EXYNOS_VIDOSD(win_id));
-
-	cfg = EXYNOS_VIDOSD_RIGHT_X(pvid->vl_col - 1) |
-		EXYNOS_VIDOSD_BOTTOM_Y(pvid->vl_row - 1) |
-		EXYNOS_VIDOSD_RIGHT_X_E(1) |
-		EXYNOS_VIDOSD_BOTTOM_Y_E(0);
-
-	writel(cfg, (unsigned int)&fimd_ctrl->vidosd0b +
-			EXYNOS_VIDOSD(win_id));
-
-	/* set window size for window0*/
-	cfg = EXYNOS_VIDOSD_SIZE(pvid->vl_col * pvid->vl_row);
-	writel(cfg, (unsigned int)&fimd_ctrl->vidosd0c +
-			EXYNOS_VIDOSD(win_id));
-}
-
-static void exynos_fimd_set_buffer_address(unsigned int win_id)
-{
-	unsigned long start_addr, end_addr;
-
-	start_addr = (unsigned long)lcd_base_addr;
-	end_addr = start_addr + ((pvid->vl_col * (NBITS(pvid->vl_bpix) / 8)) *
-				pvid->vl_row);
-
-	writel(start_addr, (unsigned int)&fimd_ctrl->vidw00add0b0 +
-			EXYNOS_BUFFER_OFFSET(win_id));
-	writel(end_addr, (unsigned int)&fimd_ctrl->vidw00add1b0 +
-			EXYNOS_BUFFER_OFFSET(win_id));
-}
-
-static void exynos_fimd_set_clock(vidinfo_t *pvid)
-{
-	unsigned int cfg = 0, div = 0, remainder, remainder_div;
-	unsigned long pixel_clock;
-	unsigned long long src_clock;
-
-	if (pvid->dual_lcd_enabled) {
-		pixel_clock = pvid->vl_freq *
-				(pvid->vl_hspw + pvid->vl_hfpd +
-				 pvid->vl_hbpd + pvid->vl_col / 2) *
-				(pvid->vl_vspw + pvid->vl_vfpd +
-				 pvid->vl_vbpd + pvid->vl_row);
-	} else if (pvid->interface_mode == FIMD_CPU_INTERFACE) {
-		pixel_clock = pvid->vl_freq *
-				pvid->vl_width * pvid->vl_height *
-				(pvid->cs_setup + pvid->wr_setup +
-				 pvid->wr_act + pvid->wr_hold + 1);
-	} else {
-		pixel_clock = pvid->vl_freq *
-				(pvid->vl_hspw + pvid->vl_hfpd +
-				 pvid->vl_hbpd + pvid->vl_col) *
-				(pvid->vl_vspw + pvid->vl_vfpd +
-				 pvid->vl_vbpd + pvid->vl_row);
-	}
-
-	cfg = readl(&fimd_ctrl->vidcon0);
-	cfg &= ~(EXYNOS_VIDCON0_CLKSEL_MASK | EXYNOS_VIDCON0_CLKVALUP_MASK |
-		EXYNOS_VIDCON0_CLKVAL_F(0xFF) | EXYNOS_VIDCON0_VCLKEN_MASK |
-		EXYNOS_VIDCON0_CLKDIR_MASK);
-	cfg |= (EXYNOS_VIDCON0_CLKSEL_SCLK | EXYNOS_VIDCON0_CLKVALUP_ALWAYS |
-		EXYNOS_VIDCON0_VCLKEN_NORMAL | EXYNOS_VIDCON0_CLKDIR_DIVIDED);
-
-	src_clock = (unsigned long long) get_lcd_clk();
-
-	/* get quotient and remainder. */
-	remainder = do_div(src_clock, pixel_clock);
-	div = src_clock;
-
-	remainder *= 10;
-	remainder_div = remainder / pixel_clock;
-
-	/* round about one places of decimals. */
-	if (remainder_div >= 5)
-		div++;
-
-	/* in case of dual lcd mode. */
-	if (pvid->dual_lcd_enabled)
-		div--;
-
-	cfg |= EXYNOS_VIDCON0_CLKVAL_F(div - 1);
-	writel(cfg, &fimd_ctrl->vidcon0);
-}
-
-void exynos_set_trigger(void)
-{
-	unsigned int cfg = 0;
-
-	cfg = readl(&fimd_ctrl->trigcon);
-
-	cfg |= (EXYNOS_I80SOFT_TRIG_EN | EXYNOS_I80START_TRIG);
-
-	writel(cfg, &fimd_ctrl->trigcon);
-}
-
-int exynos_is_i80_frame_done(void)
-{
-	unsigned int cfg = 0;
-	int status;
-
-	cfg = readl(&fimd_ctrl->trigcon);
-
-	/* frame done func is valid only when TRIMODE[0] is set to 1. */
-	status = (cfg & EXYNOS_I80STATUS_TRIG_DONE) ==
-			EXYNOS_I80STATUS_TRIG_DONE;
-
-	return status;
-}
-
-static void exynos_fimd_lcd_on(void)
-{
-	unsigned int cfg = 0;
-
-	/* display on */
-	cfg = readl(&fimd_ctrl->vidcon0);
-	cfg |= (EXYNOS_VIDCON0_ENVID_ENABLE | EXYNOS_VIDCON0_ENVID_F_ENABLE);
-	writel(cfg, &fimd_ctrl->vidcon0);
-}
-
-static void exynos_fimd_window_on(unsigned int win_id)
-{
-	unsigned int cfg = 0;
-
-	/* enable window */
-	cfg = readl((unsigned int)&fimd_ctrl->wincon0 +
-			EXYNOS_WINCON(win_id));
-	cfg |= EXYNOS_WINCON_ENWIN_ENABLE;
-	writel(cfg, (unsigned int)&fimd_ctrl->wincon0 +
-			EXYNOS_WINCON(win_id));
-
-	cfg = readl(&fimd_ctrl->winshmap);
-	cfg |= EXYNOS_WINSHMAP_CH_ENABLE(win_id);
-	writel(cfg, &fimd_ctrl->winshmap);
-}
-
-void exynos_fimd_lcd_off(void)
-{
-	unsigned int cfg = 0;
-
-	cfg = readl(&fimd_ctrl->vidcon0);
-	cfg &= (EXYNOS_VIDCON0_ENVID_DISABLE | EXYNOS_VIDCON0_ENVID_F_DISABLE);
-	writel(cfg, &fimd_ctrl->vidcon0);
-}
-
-void exynos_fimd_window_off(unsigned int win_id)
-{
-	unsigned int cfg = 0;
-
-	cfg = readl((unsigned int)&fimd_ctrl->wincon0 +
-			EXYNOS_WINCON(win_id));
-	cfg &= EXYNOS_WINCON_ENWIN_DISABLE;
-	writel(cfg, (unsigned int)&fimd_ctrl->wincon0 +
-			EXYNOS_WINCON(win_id));
-
-	cfg = readl(&fimd_ctrl->winshmap);
-	cfg &= ~EXYNOS_WINSHMAP_CH_DISABLE(win_id);
-	writel(cfg, &fimd_ctrl->winshmap);
-}
-
-#if CONFIG_IS_ENABLED(OF_CONTROL)
-/*
-* The reset value for FIMD SYSMMU register MMU_CTRL is 3
-* on Exynos5420 and newer versions.
-* This means FIMD SYSMMU is on by default on Exynos5420
-* and newer versions.
-* Since in u-boot we don't use SYSMMU, we should disable
-* those FIMD SYSMMU.
-* Note that there are 2 SYSMMU for FIMD: m0 and m1.
-* m0 handles windows 0 and 4, and m1 handles windows 1, 2 and 3.
-* We disable both of them here.
-*/
-void exynos_fimd_disable_sysmmu(void)
-{
-	u32 *sysmmufimd;
-	unsigned int node;
-	int node_list[2];
-	int count;
-	int i;
-
-	count = fdtdec_find_aliases_for_id(gd->fdt_blob, "fimd",
-				COMPAT_SAMSUNG_EXYNOS_SYSMMU, node_list, 2);
-	for (i = 0; i < count; i++) {
-		node = node_list[i];
-		if (node <= 0) {
-			debug("Can't get device node for fimd sysmmu\n");
-			return;
-		}
-
-		sysmmufimd = (u32 *)fdtdec_get_addr(gd->fdt_blob, node, "reg");
-		if (!sysmmufimd) {
-			debug("Can't get base address for sysmmu fimdm0");
-			return;
-		}
-
-		writel(0x0, sysmmufimd);
-	}
-}
-#endif
-
-void exynos_fimd_lcd_init(vidinfo_t *vid)
-{
-	unsigned int cfg = 0, rgb_mode;
-	unsigned int offset;
-#if CONFIG_IS_ENABLED(OF_CONTROL)
-	unsigned int node;
-
-	node = fdtdec_next_compatible(gd->fdt_blob,
-					0, COMPAT_SAMSUNG_EXYNOS_FIMD);
-	if (node <= 0)
-		debug("exynos_fb: Can't get device node for fimd\n");
-
-	fimd_ctrl = (struct exynos_fb *)fdtdec_get_addr(gd->fdt_blob,
-								node, "reg");
-	if (fimd_ctrl == NULL)
-		debug("Can't get the FIMD base address\n");
-
-	if (fdtdec_get_bool(gd->fdt_blob, node, "samsung,disable-sysmmu"))
-		exynos_fimd_disable_sysmmu();
-
-#else
-	fimd_ctrl = (struct exynos_fb *)samsung_get_base_fimd();
-#endif
-
-	offset = exynos_fimd_get_base_offset();
-
-	/* store panel info to global variable */
-	pvid = vid;
-
-	rgb_mode = vid->rgb_mode;
-
-	if (vid->interface_mode == FIMD_RGB_INTERFACE) {
-		cfg |= EXYNOS_VIDCON0_VIDOUT_RGB;
-		writel(cfg, &fimd_ctrl->vidcon0);
-
-		cfg = readl(&fimd_ctrl->vidcon2);
-		cfg &= ~(EXYNOS_VIDCON2_WB_MASK |
-			EXYNOS_VIDCON2_TVFORMATSEL_MASK |
-			EXYNOS_VIDCON2_TVFORMATSEL_YUV_MASK);
-		cfg |= EXYNOS_VIDCON2_WB_DISABLE;
-		writel(cfg, &fimd_ctrl->vidcon2);
-
-		/* set polarity */
-		cfg = 0;
-		if (!pvid->vl_clkp)
-			cfg |= EXYNOS_VIDCON1_IVCLK_RISING_EDGE;
-		if (!pvid->vl_hsp)
-			cfg |= EXYNOS_VIDCON1_IHSYNC_INVERT;
-		if (!pvid->vl_vsp)
-			cfg |= EXYNOS_VIDCON1_IVSYNC_INVERT;
-		if (!pvid->vl_dp)
-			cfg |= EXYNOS_VIDCON1_IVDEN_INVERT;
-
-		writel(cfg, (unsigned int)&fimd_ctrl->vidcon1 + offset);
-
-		/* set timing */
-		cfg = EXYNOS_VIDTCON0_VFPD(pvid->vl_vfpd - 1);
-		cfg |= EXYNOS_VIDTCON0_VBPD(pvid->vl_vbpd - 1);
-		cfg |= EXYNOS_VIDTCON0_VSPW(pvid->vl_vspw - 1);
-		writel(cfg, (unsigned int)&fimd_ctrl->vidtcon0 + offset);
-
-		cfg = EXYNOS_VIDTCON1_HFPD(pvid->vl_hfpd - 1);
-		cfg |= EXYNOS_VIDTCON1_HBPD(pvid->vl_hbpd - 1);
-		cfg |= EXYNOS_VIDTCON1_HSPW(pvid->vl_hspw - 1);
-
-		writel(cfg, (unsigned int)&fimd_ctrl->vidtcon1 + offset);
-
-		/* set lcd size */
-		cfg = EXYNOS_VIDTCON2_HOZVAL(pvid->vl_col - 1) |
-			EXYNOS_VIDTCON2_LINEVAL(pvid->vl_row - 1) |
-			EXYNOS_VIDTCON2_HOZVAL_E(pvid->vl_col - 1) |
-			EXYNOS_VIDTCON2_LINEVAL_E(pvid->vl_row - 1);
-
-		writel(cfg, (unsigned int)&fimd_ctrl->vidtcon2 + offset);
-	}
-
-	/* set display mode */
-	cfg = readl(&fimd_ctrl->vidcon0);
-	cfg &= ~EXYNOS_VIDCON0_PNRMODE_MASK;
-	cfg |= (rgb_mode << EXYNOS_VIDCON0_PNRMODE_SHIFT);
-	writel(cfg, &fimd_ctrl->vidcon0);
-
-	/* set par */
-	exynos_fimd_set_par(pvid->win_id);
-
-	/* set memory address */
-	exynos_fimd_set_buffer_address(pvid->win_id);
-
-	/* set buffer size */
-	cfg = EXYNOS_VIDADDR_PAGEWIDTH(pvid->vl_col * NBITS(pvid->vl_bpix) / 8) |
-		EXYNOS_VIDADDR_PAGEWIDTH_E(pvid->vl_col * NBITS(pvid->vl_bpix) / 8) |
-		EXYNOS_VIDADDR_OFFSIZE(0) |
-		EXYNOS_VIDADDR_OFFSIZE_E(0);
-
-	writel(cfg, (unsigned int)&fimd_ctrl->vidw00add2 +
-					EXYNOS_BUFFER_SIZE(pvid->win_id));
-
-	/* set clock */
-	exynos_fimd_set_clock(pvid);
-
-	/* set rgb mode to dual lcd. */
-	exynos_fimd_set_dualrgb(pvid->dual_lcd_enabled);
-
-	/* display on */
-	exynos_fimd_lcd_on();
-
-	/* window on */
-	exynos_fimd_window_on(pvid->win_id);
-
-	exynos_fimd_set_dp_clkcon(pvid->dp_enabled);
-}
-
-unsigned long exynos_fimd_calc_fbsize(void)
-{
-	return pvid->vl_col * pvid->vl_row * (NBITS(pvid->vl_bpix) / 8);
-}
diff --git a/drivers/video/s6e8ax0.c b/drivers/video/s6e8ax0.c
index 84948177e239c04319f0af65e6d9d1e9945cd66c..1bd49eef80814fb936dc946139cbe9a20faa5d37 100644
--- a/drivers/video/s6e8ax0.c
+++ b/drivers/video/s6e8ax0.c
@@ -9,8 +9,8 @@
 #include <common.h>
 #include <asm/arch/mipi_dsim.h>
 
-#include "exynos_mipi_dsi_lowlevel.h"
-#include "exynos_mipi_dsi_common.h"
+#include "exynos/exynos_mipi_dsi_lowlevel.h"
+#include "exynos/exynos_mipi_dsi_common.h"
 
 static void s6e8ax0_panel_cond(struct mipi_dsim_device *dsim_dev)
 {
diff --git a/drivers/video/simple_panel.c b/drivers/video/simple_panel.c
index 621930009707de1ceca28183c5d1e21f11f0d7a8..b2fe345ce3dea58be3b4ae11cfcb2b566877646b 100644
--- a/drivers/video/simple_panel.c
+++ b/drivers/video/simple_panel.c
@@ -88,6 +88,8 @@ static const struct panel_ops simple_panel_ops = {
 static const struct udevice_id simple_panel_ids[] = {
 	{ .compatible = "simple-panel" },
 	{ .compatible = "auo,b133xtn01" },
+	{ .compatible = "auo,b116xw03" },
+	{ .compatible = "auo,b133htn01" },
 	{ }
 };
 
diff --git a/include/configs/espresso7420.h b/include/configs/espresso7420.h
new file mode 100644
index 0000000000000000000000000000000000000000..c6a756d2b9e96e19011d0e6a9d729527836edf0e
--- /dev/null
+++ b/include/configs/espresso7420.h
@@ -0,0 +1,34 @@
+/*
+ * Configuration settings for the SAMSUNG ESPRESSO7420 board.
+ * Copyright (C) 2016 Samsung Electronics
+ * Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_ESPRESSO7420_H
+#define __CONFIG_ESPRESSO7420_H
+
+#include <configs/exynos7420-common.h>
+
+#define CONFIG_BOARD_COMMON
+
+#define CONFIG_ESPRESSO7420
+#define CONFIG_ENV_IS_NOWHERE
+
+#define CONFIG_SYS_SDRAM_BASE		0x40000000
+#define CONFIG_SYS_TEXT_BASE		0x43E00000
+#define CONFIG_SPL_STACK		CONFIG_IRAM_END
+#define CONFIG_SYS_INIT_SP_ADDR		CONFIG_IRAM_END
+
+/* select serial console configuration */
+#define CONFIG_DEFAULT_CONSOLE	"console=ttySAC1,115200n8\0"
+
+#define CONFIG_IDENT_STRING	" for ESPRESSO7420"
+#define CONFIG_DEFAULT_CONSOLE	"console=ttySAC1,115200n8\0"
+
+/* DRAM Memory Banks */
+#define CONFIG_NR_DRAM_BANKS	8
+#define SDRAM_BANK_SIZE		(256UL << 20UL)	/* 256 MB */
+
+#endif	/* __CONFIG_ESPRESSO7420_H */
diff --git a/include/configs/exynos5-common.h b/include/configs/exynos5-common.h
index e614a7f5a69540f69fda7da0265c6f4fbb462177..f2ed7982b4531f6a0abf877f5b61028dc18f65b4 100644
--- a/include/configs/exynos5-common.h
+++ b/include/configs/exynos5-common.h
@@ -60,7 +60,6 @@
 
 #define CONFIG_SPL_LIBCOMMON_SUPPORT
 #define CONFIG_SPL_GPIO_SUPPORT
-#define CONFIG_SPL_SERIAL_SUPPORT
 #define CONFIG_SPL_LIBGENERIC_SUPPORT
 
 /* specific .lds file */
@@ -124,7 +123,6 @@
 #define CONFIG_SYS_I2C_S3C24X0
 #define CONFIG_SYS_I2C_S3C24X0_SPEED	100000		/* 100 Kbps */
 #define CONFIG_SYS_I2C_S3C24X0_SLAVE    0x0
-#define CONFIG_I2C_EDID
 
 /* SPI */
 #ifdef CONFIG_SPI_FLASH
diff --git a/include/configs/exynos5-dt-common.h b/include/configs/exynos5-dt-common.h
index 8b61a52c5a27200a922c63e1c4034e11babf371d..3d81f9457d8881c639b327cf57392dad086857d5 100644
--- a/include/configs/exynos5-dt-common.h
+++ b/include/configs/exynos5-dt-common.h
@@ -13,8 +13,8 @@
 #undef EXYNOS_DEVICE_SETTINGS
 #define EXYNOS_DEVICE_SETTINGS \
 		"stdin=serial,cros-ec-keyb\0" \
-		"stdout=serial,lcd\0" \
-		"stderr=serial,lcd\0"
+		"stdout=serial,vidconsole\0" \
+		"stderr=serial,vidconsole\0"
 
 #define CONFIG_EXYNOS5_DT
 
@@ -32,6 +32,7 @@
 #define CONFIG_EXYNOS_FB
 #define CONFIG_EXYNOS_DP
 #define LCD_BPP			LCD_COLOR16
+#define CONFIG_SYS_WHITE_ON_BLACK
 #endif
 
 /* Enable keyboard */
diff --git a/include/configs/exynos7420-common.h b/include/configs/exynos7420-common.h
new file mode 100644
index 0000000000000000000000000000000000000000..9e0396208ab726d1cd9e1e4b2c531d757d6da385
--- /dev/null
+++ b/include/configs/exynos7420-common.h
@@ -0,0 +1,113 @@
+/*
+ * Configuration settings for the Espresso7420 board.
+ * Copyright (C) 2016 Samsung Electronics
+ * Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_EXYNOS7420_COMMON_H
+#define __CONFIG_EXYNOS7420_COMMON_H
+
+/* High Level Configuration Options */
+#define CONFIG_SAMSUNG			/* in a SAMSUNG core */
+#define CONFIG_EXYNOS7420		/* Exynos7 Family */
+#define CONFIG_S5P
+
+#include <asm/arch/cpu.h>		/* get chip and board defs */
+#include <linux/sizes.h>
+
+#define CONFIG_ARCH_CPU_INIT
+#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_BOARD_EARLY_INIT_F
+
+/* Size of malloc() pool before and after relocation */
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + (80 << 20))
+
+/* Miscellaneous configurable options */
+#define CONFIG_SYS_CBSIZE		1024	/* Console I/O Buffer Size */
+#define CONFIG_SYS_PBSIZE		1024	/* Print Buffer Size */
+#define CONFIG_SYS_MAXARGS		16	/* max number of command args */
+
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE		CONFIG_SYS_CBSIZE
+
+/* select serial console configuration */
+#define CONFIG_BAUDRATE			115200
+
+/* FLASH and environment organization */
+#define CONFIG_SYS_NO_FLASH
+
+/* Timer input clock frequency */
+#define COUNTER_FREQUENCY		24000000
+
+/* Device Tree */
+#define CONFIG_DEVICE_TREE_LIST "exynos7420-espresso7420"
+
+/* IRAM Layout */
+#define CONFIG_IRAM_BASE		0x02100000
+#define CONFIG_IRAM_SIZE		0x58000
+#define CONFIG_IRAM_END			(CONFIG_IRAM_BASE + CONFIG_IRAM_SIZE)
+
+/* Number of CPUs available */
+#define CONFIG_CORE_COUNT		0x8
+
+/* select serial console configuration */
+#define CONFIG_BAUDRATE			115200
+#define CONFIG_SILENT_CONSOLE
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+#define CONFIG_CONSOLE_MUX
+
+#define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x3E00000)
+
+#define PHYS_SDRAM_1		CONFIG_SYS_SDRAM_BASE
+#define PHYS_SDRAM_1_SIZE	SDRAM_BANK_SIZE
+#define PHYS_SDRAM_2		(CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE)
+#define PHYS_SDRAM_2_SIZE	SDRAM_BANK_SIZE
+#define PHYS_SDRAM_3		(CONFIG_SYS_SDRAM_BASE + (2 * SDRAM_BANK_SIZE))
+#define PHYS_SDRAM_3_SIZE	SDRAM_BANK_SIZE
+#define PHYS_SDRAM_4		(CONFIG_SYS_SDRAM_BASE + (3 * SDRAM_BANK_SIZE))
+#define PHYS_SDRAM_4_SIZE	SDRAM_BANK_SIZE
+#define PHYS_SDRAM_5		(CONFIG_SYS_SDRAM_BASE + (4 * SDRAM_BANK_SIZE))
+#define PHYS_SDRAM_5_SIZE	SDRAM_BANK_SIZE
+#define PHYS_SDRAM_6		(CONFIG_SYS_SDRAM_BASE + (5 * SDRAM_BANK_SIZE))
+#define PHYS_SDRAM_6_SIZE	SDRAM_BANK_SIZE
+#define PHYS_SDRAM_7		(CONFIG_SYS_SDRAM_BASE + (6 * SDRAM_BANK_SIZE))
+#define PHYS_SDRAM_7_SIZE	SDRAM_BANK_SIZE
+#define PHYS_SDRAM_8		(CONFIG_SYS_SDRAM_BASE + (7 * SDRAM_BANK_SIZE))
+#define PHYS_SDRAM_8_SIZE	SDRAM_BANK_SIZE
+
+/* Configuration of ENV Blocks */
+#define CONFIG_ENV_SIZE	(16 << 10) /* 16 KB */
+
+#define BOOT_TARGET_DEVICES(func) \
+	func(MMC, mmc, 1) \
+	func(MMC, mmc, 0) \
+
+#ifndef MEM_LAYOUT_ENV_SETTINGS
+#define MEM_LAYOUT_ENV_SETTINGS \
+	"bootm_size=0x10000000\0" \
+	"kernel_addr_r=0x42000000\0" \
+	"fdt_addr_r=0x43000000\0" \
+	"ramdisk_addr_r=0x43300000\0" \
+	"scriptaddr=0x50000000\0" \
+	"pxefile_addr_r=0x51000000\0"
+#endif
+
+#ifndef EXYNOS_DEVICE_SETTINGS
+#define EXYNOS_DEVICE_SETTINGS \
+	"stdin=serial\0" \
+	"stdout=serial\0" \
+	"stderr=serial\0"
+#endif
+
+#ifndef EXYNOS_FDTFILE_SETTING
+#define EXYNOS_FDTFILE_SETTING
+#endif
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	EXYNOS_DEVICE_SETTINGS \
+	EXYNOS_FDTFILE_SETTING \
+	MEM_LAYOUT_ENV_SETTINGS
+
+#endif	/* __CONFIG_EXYNOS7420_COMMON_H */
diff --git a/include/configs/s5pc210_universal.h b/include/configs/s5pc210_universal.h
index bdb368ed33baadbe03aedf4c6a81df7d2f676261..99153067b293be7001057a7025e2489c80e28ec7 100644
--- a/include/configs/s5pc210_universal.h
+++ b/include/configs/s5pc210_universal.h
@@ -217,9 +217,6 @@ int universal_spi_read(void);
 /*
  * LCD Settings
  */
-#define CONFIG_EXYNOS_FB
-#define CONFIG_LCD
-#define CONFIG_CMD_BMP
 #define CONFIG_BMP_16BPP
 #define CONFIG_LD9040
 #define CONFIG_VIDEO_BMP_GZIP
diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h
index f66bb121f32a11ad8bf98e85235afdef10fd1386..92a08332a3cc46cacd84c21b977fe2323788d5a4 100644
--- a/include/configs/smdk5250.h
+++ b/include/configs/smdk5250.h
@@ -13,6 +13,9 @@
 #include <configs/exynos5-dt-common.h>
 #include <configs/exynos5-common.h>
 
+#undef CONFIG_LCD
+#undef CONFIG_EXYNOS_FB
+#undef CONFIG_EXYNOS_DP
 #undef CONFIG_KEYBOARD
 
 #define CONFIG_BOARD_COMMON
diff --git a/include/configs/smdk5420.h b/include/configs/smdk5420.h
index c15acec89d02b563c5b1c45277347e5eb78921b9..a46ca741666ef023f43254b421a4338c59dab4a9 100644
--- a/include/configs/smdk5420.h
+++ b/include/configs/smdk5420.h
@@ -13,6 +13,10 @@
 #include <configs/exynos5-dt-common.h>
 #include <configs/exynos5-common.h>
 
+#undef CONFIG_LCD
+#undef CONFIG_EXYNOS_FB
+#undef CONFIG_EXYNOS_DP
+
 #undef CONFIG_KEYBOARD
 
 #define CONFIG_BOARD_COMMON
diff --git a/include/configs/trats.h b/include/configs/trats.h
index 0c875cb47fcd6bcfe247ca112e36afac60cfc9f3..22b0c90ee9625cc4b5c330fd637a304068b1675e 100644
--- a/include/configs/trats.h
+++ b/include/configs/trats.h
@@ -242,12 +242,8 @@
 #define CONFIG_SYS_WHITE_ON_BLACK
 
 /* LCD */
-#define CONFIG_EXYNOS_FB
-#define CONFIG_LCD
-#define CONFIG_CMD_BMP
 #define CONFIG_BMP_16BPP
 #define CONFIG_FB_ADDR		0x52504000
-#define CONFIG_S6E8AX0
 #define CONFIG_EXYNOS_MIPI_DSIM
 #define CONFIG_VIDEO_BMP_GZIP
 #define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE  ((500 * 160 * 4) + 54)
diff --git a/include/configs/trats2.h b/include/configs/trats2.h
index 492a253d73a3923663cf6a14fee8d4c024ca53a6..1febaaef51f339fae9404fa3fe584c2a0c10f058 100644
--- a/include/configs/trats2.h
+++ b/include/configs/trats2.h
@@ -222,12 +222,8 @@ int get_soft_i2c_sda_pin(void);
 #define CONFIG_SYS_WHITE_ON_BLACK
 
 /* LCD */
-#define CONFIG_EXYNOS_FB
-#define CONFIG_LCD
-#define CONFIG_CMD_BMP
 #define CONFIG_BMP_16BPP
 #define CONFIG_FB_ADDR		0x52504000
-#define CONFIG_S6E8AX0
 #define CONFIG_EXYNOS_MIPI_DSIM
 #define CONFIG_VIDEO_BMP_GZIP
 #define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE ((500 * 160 * 4) + 54)
diff --git a/include/dt-bindings/clock/exynos7420-clk.h b/include/dt-bindings/clock/exynos7420-clk.h
new file mode 100644
index 0000000000000000000000000000000000000000..10c558611085df705e982623a1934031015de461
--- /dev/null
+++ b/include/dt-bindings/clock/exynos7420-clk.h
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Author: Naveen Krishna Ch <naveenkrishna.ch@gmail.com>
+ *
+ * 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.
+*/
+
+#ifndef _DT_BINDINGS_CLOCK_EXYNOS7_H
+#define _DT_BINDINGS_CLOCK_EXYNOS7_H
+
+/* TOPC */
+#define DOUT_ACLK_PERIS			1
+#define DOUT_SCLK_BUS0_PLL		2
+#define DOUT_SCLK_BUS1_PLL		3
+#define DOUT_SCLK_CC_PLL		4
+#define DOUT_SCLK_MFC_PLL		5
+#define DOUT_ACLK_CCORE_133		6
+#define DOUT_ACLK_MSCL_532		7
+#define ACLK_MSCL_532			8
+#define DOUT_SCLK_AUD_PLL		9
+#define FOUT_AUD_PLL			10
+#define SCLK_AUD_PLL			11
+#define SCLK_MFC_PLL_B			12
+#define SCLK_MFC_PLL_A			13
+#define SCLK_BUS1_PLL_B			14
+#define SCLK_BUS1_PLL_A			15
+#define SCLK_BUS0_PLL_B			16
+#define SCLK_BUS0_PLL_A			17
+#define SCLK_CC_PLL_B			18
+#define SCLK_CC_PLL_A			19
+#define ACLK_CCORE_133			20
+#define ACLK_PERIS_66			21
+#define TOPC_NR_CLK			22
+
+/* TOP0 */
+#define DOUT_ACLK_PERIC1		1
+#define DOUT_ACLK_PERIC0		2
+#define CLK_SCLK_UART0			3
+#define CLK_SCLK_UART1			4
+#define CLK_SCLK_UART2			5
+#define CLK_SCLK_UART3			6
+#define CLK_SCLK_SPI0			7
+#define CLK_SCLK_SPI1			8
+#define CLK_SCLK_SPI2			9
+#define CLK_SCLK_SPI3			10
+#define CLK_SCLK_SPI4			11
+#define CLK_SCLK_SPDIF			12
+#define CLK_SCLK_PCM1			13
+#define CLK_SCLK_I2S1			14
+#define CLK_ACLK_PERIC0_66		15
+#define CLK_ACLK_PERIC1_66		16
+#define TOP0_NR_CLK			17
+
+/* TOP1 */
+#define DOUT_ACLK_FSYS1_200		1
+#define DOUT_ACLK_FSYS0_200		2
+#define DOUT_SCLK_MMC2			3
+#define DOUT_SCLK_MMC1			4
+#define DOUT_SCLK_MMC0			5
+#define CLK_SCLK_MMC2			6
+#define CLK_SCLK_MMC1			7
+#define CLK_SCLK_MMC0			8
+#define CLK_ACLK_FSYS0_200		9
+#define CLK_ACLK_FSYS1_200		10
+#define CLK_SCLK_PHY_FSYS1		11
+#define CLK_SCLK_PHY_FSYS1_26M		12
+#define MOUT_SCLK_UFSUNIPRO20		13
+#define DOUT_SCLK_UFSUNIPRO20		14
+#define CLK_SCLK_UFSUNIPRO20		15
+#define DOUT_SCLK_PHY_FSYS1		16
+#define DOUT_SCLK_PHY_FSYS1_26M		17
+#define TOP1_NR_CLK			18
+
+/* CCORE */
+#define PCLK_RTC			1
+#define CCORE_NR_CLK			2
+
+/* PERIC0 */
+#define PCLK_UART0			1
+#define SCLK_UART0			2
+#define PCLK_HSI2C0			3
+#define PCLK_HSI2C1			4
+#define PCLK_HSI2C4			5
+#define PCLK_HSI2C5			6
+#define PCLK_HSI2C9			7
+#define PCLK_HSI2C10			8
+#define PCLK_HSI2C11			9
+#define PCLK_PWM			10
+#define SCLK_PWM			11
+#define PCLK_ADCIF			12
+#define PERIC0_NR_CLK			13
+
+/* PERIC1 */
+#define PCLK_UART1			1
+#define PCLK_UART2			2
+#define PCLK_UART3			3
+#define SCLK_UART1			4
+#define SCLK_UART2			5
+#define SCLK_UART3			6
+#define PCLK_HSI2C2			7
+#define PCLK_HSI2C3			8
+#define PCLK_HSI2C6			9
+#define PCLK_HSI2C7			10
+#define PCLK_HSI2C8			11
+#define PCLK_SPI0			12
+#define PCLK_SPI1			13
+#define PCLK_SPI2			14
+#define PCLK_SPI3			15
+#define PCLK_SPI4			16
+#define SCLK_SPI0			17
+#define SCLK_SPI1			18
+#define SCLK_SPI2			19
+#define SCLK_SPI3			20
+#define SCLK_SPI4			21
+#define PCLK_I2S1			22
+#define PCLK_PCM1			23
+#define PCLK_SPDIF			24
+#define SCLK_I2S1			25
+#define SCLK_PCM1			26
+#define SCLK_SPDIF			27
+#define PERIC1_NR_CLK			28
+
+/* PERIS */
+#define PCLK_CHIPID			1
+#define SCLK_CHIPID			2
+#define PCLK_WDT			3
+#define PCLK_TMU			4
+#define SCLK_TMU			5
+#define PERIS_NR_CLK			6
+
+/* FSYS0 */
+#define ACLK_MMC2			1
+#define ACLK_AXIUS_USBDRD30X_FSYS0X	2
+#define ACLK_USBDRD300			3
+#define SCLK_USBDRD300_SUSPENDCLK	4
+#define SCLK_USBDRD300_REFCLK		5
+#define PHYCLK_USBDRD300_UDRD30_PIPE_PCLK_USER		6
+#define PHYCLK_USBDRD300_UDRD30_PHYCLK_USER		7
+#define OSCCLK_PHY_CLKOUT_USB30_PHY		8
+#define ACLK_PDMA0			9
+#define ACLK_PDMA1			10
+#define FSYS0_NR_CLK			11
+
+/* FSYS1 */
+#define ACLK_MMC1			1
+#define ACLK_MMC0			2
+#define PHYCLK_UFS20_TX0_SYMBOL		3
+#define PHYCLK_UFS20_RX0_SYMBOL		4
+#define PHYCLK_UFS20_RX1_SYMBOL		5
+#define ACLK_UFS20_LINK			6
+#define SCLK_UFSUNIPRO20_USER		7
+#define PHYCLK_UFS20_RX1_SYMBOL_USER	8
+#define PHYCLK_UFS20_RX0_SYMBOL_USER	9
+#define PHYCLK_UFS20_TX0_SYMBOL_USER	10
+#define OSCCLK_PHY_CLKOUT_EMBEDDED_COMBO_PHY	11
+#define SCLK_COMBO_PHY_EMBEDDED_26M	12
+#define DOUT_PCLK_FSYS1			13
+#define PCLK_GPIO_FSYS1			14
+#define MOUT_FSYS1_PHYCLK_SEL1		15
+#define FSYS1_NR_CLK			16
+
+/* MSCL */
+#define USERMUX_ACLK_MSCL_532		1
+#define DOUT_PCLK_MSCL			2
+#define ACLK_MSCL_0			3
+#define ACLK_MSCL_1			4
+#define ACLK_JPEG			5
+#define ACLK_G2D			6
+#define ACLK_LH_ASYNC_SI_MSCL_0		7
+#define ACLK_LH_ASYNC_SI_MSCL_1		8
+#define ACLK_AXI2ACEL_BRIDGE		9
+#define ACLK_XIU_MSCLX_0		10
+#define ACLK_XIU_MSCLX_1		11
+#define ACLK_QE_MSCL_0			12
+#define ACLK_QE_MSCL_1			13
+#define ACLK_QE_JPEG			14
+#define ACLK_QE_G2D			15
+#define ACLK_PPMU_MSCL_0		16
+#define ACLK_PPMU_MSCL_1		17
+#define ACLK_MSCLNP_133			18
+#define ACLK_AHB2APB_MSCL0P		19
+#define ACLK_AHB2APB_MSCL1P		20
+
+#define PCLK_MSCL_0			21
+#define PCLK_MSCL_1			22
+#define PCLK_JPEG			23
+#define PCLK_G2D			24
+#define PCLK_QE_MSCL_0			25
+#define PCLK_QE_MSCL_1			26
+#define PCLK_QE_JPEG			27
+#define PCLK_QE_G2D			28
+#define PCLK_PPMU_MSCL_0		29
+#define PCLK_PPMU_MSCL_1		30
+#define PCLK_AXI2ACEL_BRIDGE		31
+#define PCLK_PMU_MSCL			32
+#define MSCL_NR_CLK			33
+
+/* AUD */
+#define SCLK_I2S			1
+#define SCLK_PCM			2
+#define PCLK_I2S			3
+#define PCLK_PCM			4
+#define ACLK_ADMA			5
+#define AUD_NR_CLK			6
+#endif /* _DT_BINDINGS_CLOCK_EXYNOS7_H */
diff --git a/include/dt-bindings/clock/maxim,max77802.h b/include/dt-bindings/clock/maxim,max77802.h
new file mode 100644
index 0000000000000000000000000000000000000000..997312edcbb5b059375f1c31e745bb66568411ed
--- /dev/null
+++ b/include/dt-bindings/clock/maxim,max77802.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2014 Google, 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.
+ *
+ * Device Tree binding constants clocks for the Maxim 77802 PMIC.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_MAXIM_MAX77802_CLOCK_H
+#define _DT_BINDINGS_CLOCK_MAXIM_MAX77802_CLOCK_H
+
+/* Fixed rate clocks. */
+
+#define MAX77802_CLK_32K_AP		0
+#define MAX77802_CLK_32K_CP		1
+
+/* Total number of clocks. */
+#define MAX77802_CLKS_NUM		(MAX77802_CLK_32K_CP + 1)
+
+#endif /* _DT_BINDINGS_CLOCK_MAXIM_MAX77802_CLOCK_H */
diff --git a/include/dt-bindings/regulator/maxim,max77802.h b/include/dt-bindings/regulator/maxim,max77802.h
new file mode 100644
index 0000000000000000000000000000000000000000..cf28631d71091417a032bc0308c2e93c19bf2097
--- /dev/null
+++ b/include/dt-bindings/regulator/maxim,max77802.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2014 Google, 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.
+ *
+ * Device Tree binding constants for the Maxim 77802 PMIC regulators
+ */
+
+#ifndef _DT_BINDINGS_REGULATOR_MAXIM_MAX77802_H
+#define _DT_BINDINGS_REGULATOR_MAXIM_MAX77802_H
+
+/* Regulator operating modes */
+#define MAX77802_OPMODE_LP	1
+#define MAX77802_OPMODE_NORMAL	3
+
+#endif /* _DT_BINDINGS_REGULATOR_MAXIM_MAX77802_H */
diff --git a/include/exynos_lcd.h b/include/exynos_lcd.h
index 3969a6a06662408482aa06b521a5a619ef8ffa16..ab92ffb72ad514d120718eca0d674b62ca367c62 100644
--- a/include/exynos_lcd.h
+++ b/include/exynos_lcd.h
@@ -75,8 +75,8 @@ typedef struct vidinfo {
 	unsigned int sclk_div;
 
 	unsigned int dual_lcd_enabled;
+	struct exynos_fb *reg;
+	struct exynos_platform_mipi_dsim *dsim_platform_data_dt;
 } vidinfo_t;
 
-void init_panel_info(vidinfo_t *vid);
-
 #endif
diff --git a/include/libtizen.h b/include/libtizen.h
index 6490fb52ba3c1eb855c650cbb9bdeb40e0a11c74..55dccff715de2c2eae0a1b1b38471a1b09854084 100644
--- a/include/libtizen.h
+++ b/include/libtizen.h
@@ -10,6 +10,8 @@
 
 #define HD_RESOLUTION	0
 
+#ifdef CONFIG_LCD
 void get_tizen_logo_info(vidinfo_t *vid);
+#endif
 
 #endif	/* _LIBTIZEN_H_ */
diff --git a/include/video.h b/include/video.h
index c434bc71ae5601ee4ad0a0fcf73680a663cf98b2..0d5bd21c600e7fe503617ca0017419f0f819a090 100644
--- a/include/video.h
+++ b/include/video.h
@@ -23,6 +23,11 @@ struct video_uc_platdata {
 	ulong base;
 };
 
+enum video_polarity {
+	VIDEO_ACTIVE_HIGH,	/* Pins are active high */
+	VIDEO_ACTIVE_LOW,	/* Pins are active low */
+};
+
 /*
  * Bits per pixel selector. Each value n is such that the bits-per-pixel is
  * 2 ^ n
diff --git a/lib/tizen/tizen.c b/lib/tizen/tizen.c
index 814ed18329e01e5c7000344c795dab52c719ccea..d207f77d0b32dfd869dcded544b0d469fcdac776 100644
--- a/lib/tizen/tizen.c
+++ b/lib/tizen/tizen.c
@@ -12,6 +12,7 @@
 #include "tizen_logo_16bpp.h"
 #include "tizen_logo_16bpp_gzip.h"
 
+#ifdef CONFIG_LCD
 void get_tizen_logo_info(vidinfo_t *vid)
 {
 	switch (vid->vl_bpix) {
@@ -31,3 +32,4 @@ void get_tizen_logo_info(vidinfo_t *vid)
 		break;
 	}
 }
+#endif