diff --git a/Documentation/devicetree/bindings/display/fsl,dcu.txt b/Documentation/devicetree/bindings/display/fsl,dcu.txt
index ebf1be9..8153c9a 100644
--- a/Documentation/devicetree/bindings/display/fsl,dcu.txt
+++ b/Documentation/devicetree/bindings/display/fsl,dcu.txt
@@ -11,6 +11,9 @@ Required properties:
 - big-endian		Boolean property, LS1021A DCU registers are big-endian.
 - fsl,panel:		The phandle to panel node.
 
+Optional properties:
+- fsl,tcon:		The phandle to the timing controller node.
+
 Examples:
 dcu: dcu@2ce0000 {
 	compatible = "fsl,ls1021a-dcu";
@@ -19,4 +22,5 @@ dcu: dcu@2ce0000 {
 	clock-names = "dcu";
 	big-endian;
 	fsl,panel = <&panel>;
+	fsl,tcon = <&tcon>;
 };
diff --git a/Documentation/devicetree/bindings/display/fsl,tcon.txt b/Documentation/devicetree/bindings/display/fsl,tcon.txt
new file mode 100644
index 0000000..2e1015e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/fsl,tcon.txt
@@ -0,0 +1,18 @@
+Device Tree bindings for Freescale TCON Driver
+
+Required properties:
+- compatible:		Should be one of
+	* "fsl,vf610-tcon".
+
+- reg:			Address and length of the register set for dcu.
+- clocks:		From common clock binding: handle to tcon ipg clock.
+- clock-names:		From common clock binding: Shall be "ipg".
+
+Examples:
+timing-controller@4003d000 {
+	compatible = "fsl,vf610-tcon";
+	reg = <0x4003d000 0x1000>;
+	clocks = <&clks VF610_CLK_TCON0>;
+	clock-names = "ipg";
+	status = "okay";
+};
diff --git a/drivers/gpu/drm/fsl-dcu/Makefile b/drivers/gpu/drm/fsl-dcu/Makefile
index 6ea1523..b35a292 100644
--- a/drivers/gpu/drm/fsl-dcu/Makefile
+++ b/drivers/gpu/drm/fsl-dcu/Makefile
@@ -3,5 +3,6 @@ fsl-dcu-drm-y := fsl_dcu_drm_drv.o \
 		 fsl_dcu_drm_rgb.o \
 		 fsl_dcu_drm_plane.o \
 		 fsl_dcu_drm_crtc.o \
-		 fsl_dcu_drm_fbdev.o
+		 fsl_dcu_drm_fbdev.o \
+		 fsl_tcon.o
 obj-$(CONFIG_DRM_FSL_DCU)	+= fsl-dcu-drm.o
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index e01c813..679cde8 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -27,6 +27,7 @@
 
 #include "fsl_dcu_drm_crtc.h"
 #include "fsl_dcu_drm_drv.h"
+#include "fsl_tcon.h"
 
 static bool fsl_dcu_drm_is_volatile_reg(struct device *dev, unsigned int reg)
 {
@@ -218,6 +219,7 @@ static int fsl_dcu_drm_pm_suspend(struct device *dev)
 	drm_kms_helper_poll_disable(fsl_dev->drm);
 	regcache_cache_only(fsl_dev->regmap, true);
 	regcache_mark_dirty(fsl_dev->regmap);
+	fsl_tcon_suspend(fsl_dev->tcon);
 	clk_disable(fsl_dev->clk);
 	clk_unprepare(fsl_dev->clk);
 
@@ -244,6 +246,8 @@ static int fsl_dcu_drm_pm_resume(struct device *dev)
 		return ret;
 	}
 
+	fsl_tcon_resume(fsl_dev->tcon);
+
 	drm_kms_helper_poll_enable(fsl_dev->drm);
 	regcache_cache_only(fsl_dev->regmap, false);
 	regcache_sync(fsl_dev->regmap);
@@ -338,6 +342,8 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
 		return PTR_ERR(fsl_dev->regmap);
 	}
 
+	fsl_dev->tcon = fsl_tcon_init(dev);
+
 	id = of_match_node(fsl_dcu_of_match, pdev->dev.of_node);
 	if (!id)
 		return -ENODEV;
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
index 2a724f3..a8919f6 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
@@ -183,6 +183,7 @@ struct fsl_dcu_drm_device {
 	struct regmap *regmap;
 	int irq;
 	struct clk *clk;
+	struct fsl_tcon *tcon;
 	/*protects hardware register*/
 	spinlock_t irq_lock;
 	struct drm_device *drm;
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
index fe8ab5d..65a2df0 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
@@ -17,6 +17,7 @@
 #include <drm/drm_panel.h>
 
 #include "fsl_dcu_drm_drv.h"
+#include "fsl_tcon.h"
 
 static int
 fsl_dcu_drm_encoder_atomic_check(struct drm_encoder *encoder,
@@ -28,10 +29,20 @@ fsl_dcu_drm_encoder_atomic_check(struct drm_encoder *encoder,
 
 static void fsl_dcu_drm_encoder_disable(struct drm_encoder *encoder)
 {
+	struct drm_device *dev = encoder->dev;
+	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
+
+	if (fsl_dev->tcon)
+		fsl_tcon_disable(fsl_dev->tcon);
 }
 
 static void fsl_dcu_drm_encoder_enable(struct drm_encoder *encoder)
 {
+	struct drm_device *dev = encoder->dev;
+	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
+
+	if (fsl_dev->tcon)
+		fsl_tcon_enable(fsl_dev->tcon);
 }
 
 static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_tcon.c b/drivers/gpu/drm/fsl-dcu/fsl_tcon.c
new file mode 100644
index 0000000..de3c58b
--- /dev/null
+++ b/drivers/gpu/drm/fsl-dcu/fsl_tcon.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2015 Toradex AG
+ *
+ * Stefan Agner <stefan@agner.ch>
+ *
+ * Freescale TCON device driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "fsl_tcon.h"
+
+void fsl_tcon_disable(struct fsl_tcon *tcon)
+{
+	regmap_update_bits(tcon->regs, FSL_TCON_CTRL1,
+			   FSL_TCON_CTRL1_TCON_BYPASS, 0);
+
+	tcon->enabled = false;
+}
+
+void fsl_tcon_enable(struct fsl_tcon *tcon)
+{
+	regmap_update_bits(tcon->regs, FSL_TCON_CTRL1,
+			   FSL_TCON_CTRL1_TCON_BYPASS,
+			   FSL_TCON_CTRL1_TCON_BYPASS);
+
+	tcon->enabled = true;
+}
+
+void fsl_tcon_suspend(struct fsl_tcon *tcon)
+{
+	regmap_update_bits(tcon->regs, FSL_TCON_CTRL1,
+			   FSL_TCON_CTRL1_TCON_BYPASS, 0);
+
+	clk_disable_unprepare(tcon->ipg_clk);
+}
+
+void fsl_tcon_resume(struct fsl_tcon *tcon)
+{
+	clk_prepare_enable(tcon->ipg_clk);
+
+	if (!tcon->enabled)
+		return;
+
+	regmap_update_bits(tcon->regs, FSL_TCON_CTRL1,
+			   FSL_TCON_CTRL1_TCON_BYPASS,
+			   FSL_TCON_CTRL1_TCON_BYPASS);
+}
+
+static struct regmap_config fsl_tcon_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+
+	.name = "tcon",
+};
+
+static int fsl_tcon_init_regmap(struct device *dev,
+				struct fsl_tcon *tcon,
+				struct device_node *np)
+{
+	struct resource res;
+	void __iomem *regs;
+	int ret;
+
+	ret = of_address_to_resource(np, 0, &res);
+	regs = devm_ioremap_resource(dev, &res);
+	if (IS_ERR(regs)) {
+		dev_err(dev, "Couldn't map the TCON registers\n");
+		return PTR_ERR(regs);
+	}
+
+	tcon->regs = devm_regmap_init_mmio(dev, regs,
+					   &fsl_tcon_regmap_config);
+	if (IS_ERR(tcon->regs)) {
+		dev_err(dev, "Couldn't create the TCON regmap\n");
+		return PTR_ERR(tcon->regs);
+	}
+
+	return 0;
+}
+
+struct fsl_tcon *fsl_tcon_init(struct device *dev)
+{
+	struct fsl_tcon *tcon;
+	struct device_node *np;
+	int ret;
+
+	tcon = devm_kzalloc(dev, sizeof(*tcon), GFP_KERNEL);
+	if (!tcon)
+		return NULL;
+
+	np = of_parse_phandle(dev->of_node, "fsl,tcon", 0);
+	if (!np) {
+		dev_warn(dev, "Couldn't find the tcon node\n");
+		return NULL;
+	}
+
+	ret = fsl_tcon_init_regmap(dev, tcon, np);
+	if (ret)
+		goto err_node_put;
+
+	tcon->ipg_clk = of_clk_get_by_name(np, "ipg");
+	if (IS_ERR(tcon->ipg_clk)) {
+		dev_err(dev, "Couldn't get the TCON bus clock\n");
+		goto err_free_regmap;
+	}
+
+	clk_prepare_enable(tcon->ipg_clk);
+
+	return tcon;
+
+err_free_regmap:
+err_node_put:
+	of_node_put(np);
+	return NULL;
+}
+
+void fsl_tcon_free(struct fsl_tcon *tcon)
+{
+	clk_disable_unprepare(tcon->ipg_clk);
+	clk_put(tcon->ipg_clk);
+}
+
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_tcon.h b/drivers/gpu/drm/fsl-dcu/fsl_tcon.h
new file mode 100644
index 0000000..199e6a1
--- /dev/null
+++ b/drivers/gpu/drm/fsl-dcu/fsl_tcon.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2015 Toradex AG
+ *
+ * Stefan Agner <stefan@agner.ch>
+ *
+ * Freescale TCON device driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __FSL_TCON_H__
+#define __FSL_TCON_H__
+
+#include <linux/bitops.h>
+
+#define FSL_TCON_CTRL1			0x0
+#define FSL_TCON_CTRL1_TCON_BYPASS	BIT(29)
+
+struct fsl_tcon {
+	struct regmap		*regs;
+	struct clk		*ipg_clk;
+
+	bool			enabled;
+};
+
+struct fsl_tcon *fsl_tcon_init(struct device *dev);
+void fsl_tcon_free(struct fsl_tcon *tcon);
+
+void fsl_tcon_disable(struct fsl_tcon *tcon);
+void fsl_tcon_enable(struct fsl_tcon *tcon);
+void fsl_tcon_suspend(struct fsl_tcon *tcon);
+void fsl_tcon_resume(struct fsl_tcon *tcon);
+
+#endif /* __FSL_TCON_H__ */
