diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 807c7fa..62c3d1a 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2444,6 +2444,7 @@ source "drivers/video/omap/Kconfig"
 source "drivers/video/omap2/Kconfig"
 source "drivers/video/exynos/Kconfig"
 source "drivers/video/backlight/Kconfig"
+source "drivers/video/display/Kconfig"
 
 if VT
 	source "drivers/video/console/Kconfig"
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index f592f3b..4a091d4 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -14,6 +14,7 @@ fb-objs                           := $(fb-y)
 obj-$(CONFIG_VT)		  += console/
 obj-$(CONFIG_LOGO)		  += logo/
 obj-y				  += backlight/
+obj-y				  += display/
 
 obj-$(CONFIG_EXYNOS_VIDEO)     += exynos/
 
diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig
new file mode 100644
index 0000000..1d533e7
--- /dev/null
+++ b/drivers/video/display/Kconfig
@@ -0,0 +1,4 @@
+menuconfig DISPLAY_CORE
+	tristate "Display Core"
+	---help---
+	  Support common display framework for graphics devices.
diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile
new file mode 100644
index 0000000..bd93496
--- /dev/null
+++ b/drivers/video/display/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_DISPLAY_CORE) += display-core.o
diff --git a/drivers/video/display/display-core.c b/drivers/video/display/display-core.c
new file mode 100644
index 0000000..7950e35
--- /dev/null
+++ b/drivers/video/display/display-core.c
@@ -0,0 +1,377 @@
+/*
+ * Display Core
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.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.
+ */
+
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+
+#include <video/display.h>
+#include <video/videomode.h>
+
+static LIST_HEAD(display_entity_list);
+static DEFINE_MUTEX(display_entity_mutex);
+
+/* -----------------------------------------------------------------------------
+ * Control operations
+ */
+
+/**
+ * display_entity_set_state - Set the display entity operation state
+ * @entity: The display entity
+ * @state: Display entity operation state
+ *
+ * See &enum display_entity_state for information regarding the entity states.
+ *
+ * Return 0 on success or a negative error code otherwise.
+ */
+int display_entity_set_state(struct display_entity *entity,
+			     enum display_entity_state state)
+{
+	int ret;
+
+	if (entity->state == state)
+		return 0;
+
+	ret =  display_entity_call(entity, set_state, state);
+	if (ret < 0)
+		return ret;
+
+	entity->state = state;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(display_entity_set_state);
+
+/**
+ * display_entity_update - Update the display
+ * @entity: The display entity
+ *
+ * Make the display entity ready to receive pixel data and start frame transfer.
+ * This operation can only be called if the display entity is in STANDBY or ON
+ * state.
+ *
+ * The display entity will call the upstream entity in the video chain to start
+ * the video stream.
+ *
+ * Return 0 on success or a negative error code otherwise.
+ */
+int display_entity_update(struct display_entity *entity)
+{
+	return display_entity_call(entity, update);
+}
+EXPORT_SYMBOL_GPL(display_entity_update);
+
+/**
+ * display_entity_get_modes - Get video modes supported by the display entity
+ * @entity The display entity
+ * @modes: Pointer to an array of modes
+ *
+ * Fill the modes argument with a pointer to an array of video modes. The array
+ * is owned by the display entity.
+ *
+ * Return the number of supported modes on success (including 0 if no mode is
+ * supported) or a negative error code otherwise.
+ */
+int display_entity_get_modes(struct display_entity *entity,
+			     const struct videomode **modes)
+{
+	return display_entity_call(entity, get_modes, modes);
+}
+EXPORT_SYMBOL_GPL(display_entity_get_modes);
+
+/**
+ * display_entity_get_size - Get display entity physical size
+ * @entity: The display entity
+ * @width: Physical width in millimeters
+ * @height: Physical height in millimeters
+ *
+ * When applicable, for instance for display panels, retrieve the display
+ * physical size in millimeters.
+ *
+ * Return 0 on success or a negative error code otherwise.
+ */
+int display_entity_get_size(struct display_entity *entity,
+			    unsigned int *width, unsigned int *height)
+{
+	return display_entity_call(entity, get_size, width, height);
+}
+EXPORT_SYMBOL_GPL(display_entity_get_size);
+
+/**
+ * display_entity_get_params - Get display entity interface parameters
+ * @entity: The display entity
+ * @params: Pointer to interface parameters
+ *
+ * Fill the parameters structure pointed to by the params argument with display
+ * entity interface parameters.
+ *
+ * Return 0 on success or a negative error code otherwise.
+ */
+int display_entity_get_params(struct display_entity *entity,
+			      struct display_entity_interface_params *params)
+{
+	return display_entity_call(entity, get_params, params);
+}
+EXPORT_SYMBOL_GPL(display_entity_get_params);
+
+/* -----------------------------------------------------------------------------
+ * Video operations
+ */
+
+/**
+ * display_entity_set_stream - Control the video stream state
+ * @source: The video source port
+ * @state: Display video stream state
+ *
+ * Control the video stream state at the given entity video source port.
+ *
+ * See &enum display_entity_stream_state for information regarding the stream
+ * states.
+ *
+ * Return 0 on success or a negative error code otherwise.
+ */
+int display_entity_set_stream(struct display_entity_port *source,
+			      enum display_entity_stream_state state)
+{
+	return display_entity_port_call(source, common, set_stream, state);
+}
+EXPORT_SYMBOL_GPL(display_entity_set_stream);
+
+/* -----------------------------------------------------------------------------
+ * Connections
+ */
+
+/*
+ * display_entity_get_source - Get the source port of the given entity
+ * @entity: the entity
+ *
+ * See display_entity_register() for information about how the source port is
+ * located.
+ *
+ * Return a pointer to the source port if found, NULL if the entity has no
+ * source port, or an error pointer otherwise. If the source port is validly
+ * specified but can't be located, return ERR_PTR(-EPROBE_DEFER).
+ */
+static struct display_entity_port *
+display_entity_get_source(struct display_entity *entity)
+{
+	struct display_entity *source;
+	unsigned int source_port;
+
+	if (entity->of_node) {
+		struct device_node *np;
+		const __be32 *prop;
+		int size;
+
+		prop = of_get_property(entity->of_node, "video-source", &size);
+		if (prop == NULL)
+			return NULL;
+
+		if (size < sizeof(*prop) * 2)
+			return ERR_PTR(-EINVAL);
+
+		np = of_find_node_by_phandle(be32_to_cpup(prop));
+		if (!np)
+			return ERR_PTR(-EINVAL);
+
+		source_port = be32_to_cpup(&prop[1]);
+	} else if (entity->source_name) {
+		source_port = entity->source_port;
+
+		list_for_each_entry(source, &display_entity_list, list) {
+			if (!strcmp(source->name, entity->source_name))
+				break;
+		}
+	} else {
+		return NULL;
+	}
+
+	if (&source->list == &display_entity_list)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	if (source_port >= source->num_ports)
+		return ERR_PTR(-EINVAL);
+
+	return &source->ports[source_port];
+}
+
+/*
+ * display_entity_bind - Bind an entity to its source port
+ * @entity: the entity
+ */
+static int display_entity_bind(struct display_entity *entity)
+{
+	struct display_entity_port *source;
+	int ret;
+
+	if (entity->source)
+		return 0;
+
+	mutex_lock(&display_entity_mutex);
+
+	source = display_entity_get_source(entity);
+	if (IS_ERR_OR_NULL(source)) {
+		/* NULL means that the entity has no source. This is a valid
+		 * situation, return 0 in that case.
+		 */
+		ret = PTR_ERR(source);
+		goto done;
+	}
+
+	ret = display_entity_port_call(source, common, bind, entity);
+	if (ret < 0 && ret != -ENOIOCTLCMD)
+		goto done;
+
+	display_entity_get(source->entity);
+
+	source->sink = entity;
+	entity->source = source;
+
+	ret = 0;
+
+done:
+	mutex_unlock(&display_entity_mutex);
+	return ret;
+}
+
+/*
+ * display_entity_bind - Unbind an entity from its source port
+ * @entity: the entity
+ */
+static void display_entity_unbind(struct display_entity *entity)
+{
+	struct display_entity_port *source = entity->source;
+
+	if (!source)
+		return;
+
+	display_entity_port_call(source, common, unbind, entity);
+
+	source->sink = NULL;
+	entity->source = NULL;
+
+	display_entity_put(source->entity);
+}
+
+/* -----------------------------------------------------------------------------
+ * Registration
+ */
+
+static void display_entity_release(struct kref *ref)
+{
+	struct display_entity *entity =
+		container_of(ref, struct display_entity, ref);
+
+	if (entity->release)
+		entity->release(entity);
+}
+
+/**
+ * display_entity_get - get a reference to a display entity
+ * @display_entity: the display entity
+ *
+ * Return the display entity pointer.
+ */
+struct display_entity *display_entity_get(struct display_entity *entity)
+{
+	if (entity == NULL)
+		return NULL;
+
+	if (try_module_get(entity->owner))
+		return NULL;
+
+	kref_get(&entity->ref);
+	return entity;
+}
+EXPORT_SYMBOL_GPL(display_entity_get);
+
+/**
+ * display_entity_put - release a reference to a display entity
+ * @display_entity: the display entity
+ *
+ * Releasing the last reference to a display entity releases the display entity
+ * itself.
+ */
+void display_entity_put(struct display_entity *entity)
+{
+	module_put(entity->owner);
+	kref_put(&entity->ref, display_entity_release);
+}
+EXPORT_SYMBOL_GPL(display_entity_put);
+
+/**
+ * display_entity_register - register a display entity
+ * @display_entity: display entity to be registered
+ *
+ * This function initializes the display entity, binds it to its source port
+ * and registers it.
+ *
+ * When the entity has an associated OF node, the source port if located using
+ * the video-source property that contains a phandle to the source entity and a
+ * port number. If the video-source property is absent, the entity is considered
+ * as having no source port
+ *
+ * For non-OF entities, the source_name and source_port fields are used to match
+ * ports using their entity name and port index. If the source_name field is
+ * NULL, the entity is considered as having no source port.
+ *
+ * An entity that has no source port will not be bound. This isn't considered as
+ * an error.
+ *
+ * Return 0 on success and a negative error code otherwise. If the source port
+ * is validly specified but can't be located, return -EPROBE_DEFER.
+ */
+int __must_check __display_entity_register(struct display_entity *entity,
+					   struct module *owner)
+{
+	int ret;
+
+	kref_init(&entity->ref);
+	entity->owner = owner;
+	entity->state = DISPLAY_ENTITY_STATE_OFF;
+
+	ret = display_entity_bind(entity);
+	if (ret < 0)
+		return ret;
+
+	mutex_lock(&display_entity_mutex);
+	list_add(&entity->list, &display_entity_list);
+	mutex_unlock(&display_entity_mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(__display_entity_register);
+
+/**
+ * display_entity_unregister - unregister a display entity
+ * @display_entity: display entity to be unregistered
+ *
+ * Unregister the display entity. If no other reference to the entity exists the
+ * entity will be released and destroyed.
+ */
+void display_entity_unregister(struct display_entity *entity)
+{
+	mutex_lock(&display_entity_mutex);
+	list_del(&entity->list);
+	mutex_unlock(&display_entity_mutex);
+
+	display_entity_unbind(entity);
+	display_entity_put(entity);
+}
+EXPORT_SYMBOL_GPL(display_entity_unregister);
+
+MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+MODULE_DESCRIPTION("Display Core");
+MODULE_LICENSE("GPL");
diff --git a/include/video/display.h b/include/video/display.h
new file mode 100644
index 0000000..a80154f
--- /dev/null
+++ b/include/video/display.h
@@ -0,0 +1,293 @@
+/*
+ * Display Core
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.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 __DISPLAY_H__
+#define __DISPLAY_H__
+
+#include <linux/kref.h>
+#include <linux/list.h>
+#include <linux/module.h>
+
+struct display_entity;
+struct videomode;
+
+/* -----------------------------------------------------------------------------
+ * DSI
+ */
+
+/* 22 pins means 1 clk lane and 10 data lanes */
+#define MIPI_DSI_MAX_PINS		22
+
+struct mipi_dsi_pin_config {
+	unsigned int num_pins;
+	/*
+	 * pin numbers in the following order:
+	 * clk+, clk-
+	 * data1+, data1-
+	 * data2+, data2-
+	 * ...
+	 */
+	unsigned int pins[MIPI_DSI_MAX_PINS];
+};
+
+#define DSI_MODE_VIDEO			(1 << 0)
+#define DSI_MODE_VIDEO_BURST		(1 << 1)
+#define DSI_MODE_VIDEO_SYNC_PULSE	(1 << 2)
+#define DSI_MODE_VIDEO_AUTO_VERT	(1 << 3)
+#define DSI_MODE_VIDEO_HSE		(1 << 4)
+#define DSI_MODE_VIDEO_HFP		(1 << 5)
+#define DSI_MODE_VIDEO_HBP		(1 << 6)
+#define DSI_MODE_VIDEO_HSA		(1 << 7)
+#define DSI_MODE_VSYNC_FLUSH		(1 << 8)
+#define DSI_MODE_EOT_PACKET		(1 << 9)
+
+enum mipi_dsi_pixel_format {
+	DSI_FMT_RGB888,
+	DSI_FMT_RGB666,
+	DSI_FMT_RGB666_PACKED,
+	DSI_FMT_RGB565,
+};
+
+struct mipi_dsi_interface_params {
+	enum mipi_dsi_pixel_format format;
+	unsigned long mode;
+	unsigned long hs_clk_freq;
+	unsigned long esc_clk_freq;
+	unsigned char data_lanes;
+	unsigned char cmd_allow;
+};
+
+/* -----------------------------------------------------------------------------
+ * Display Entity Port
+ */
+
+/**
+ * struct display_entity_port - A display entity port
+ * @entity: entity that the port belongs to
+ * @index: port index in the entity (0-based)
+ * @sink: sink entity this port is connected to
+ */
+struct display_entity_port {
+	struct display_entity *entity;
+	unsigned int index;
+
+	struct display_entity *sink;
+};
+
+/* -----------------------------------------------------------------------------
+ * Display Entity Video Operations
+ */
+
+/**
+ * enum display_entity_stream_state - State of a video stream
+ * @DISPLAY_ENTITY_STREAM_STOPPED: The video stream is stopped, no frames are
+ *	transferred.
+ * @DISPLAY_ENTITY_STREAM_SINGLE_SHOT: The video stream has been started for
+ *      single shot operation. The source entity will transfer a single frame
+ *      and then stop.
+ * @DISPLAY_ENTITY_STREAM_CONTINUOUS: The video stream is running, frames are
+ *	transferred continuously by the source entity.
+ */
+enum display_entity_stream_state {
+	DISPLAY_ENTITY_STREAM_STOPPED,
+	DISPLAY_ENTITY_STREAM_SINGLE_SHOT,
+	DISPLAY_ENTITY_STREAM_CONTINUOUS,
+};
+
+struct display_entity_video_common_ops {
+	int (*set_stream)(struct display_entity_port *port,
+			  enum display_entity_stream_state state);
+	int (*bind)(struct display_entity_port *source,
+		    struct display_entity *sink);
+	int (*unbind)(struct display_entity_port *source,
+		      struct display_entity *sink);
+};
+
+struct display_entity_video_dpi_ops {
+	int (*set_videomode)(struct display_entity_port *port,
+			     const struct videomode *vm);
+	int (*set_data_lines)(struct display_entity_port *port, int lines);
+};
+
+struct display_entity_video_dsi_ops {
+	/* enable/disable dsi bus */
+	int (*enable)(struct display_entity_port *port);
+	int (*disable)(struct display_entity_port *port);
+
+	/* bus configuration */
+	int (*configure_pins)(struct display_entity_port *port,
+			      const struct mipi_dsi_pin_config *pins);
+	int (*set_clocks)(struct display_entity_port *port,
+			  unsigned long ddr_clk, unsigned long lp_clk);
+	/* NOTE: Do we really need configure_pins and set_clocks here? */
+
+	void (*enable_hs)(struct display_entity_port *port, bool enable);
+
+	/* data transfer */
+	int (*dcs_write)(struct display_entity_port *port, int channel,
+			 const u8 *data, size_t len);
+	int (*dcs_read)(struct display_entity_port *port, int channel,
+			u8 dcs_cmd, u8 *data, size_t len);
+	/* NOTE: Do we need more write and read types? */
+
+	int (*update)(struct display_entity_port *port, int channel,
+		      void (*callback)(int, void *), void *data);
+};
+
+struct display_entity_video_dvi_ops {
+	int (*set_videomode)(struct display_entity_port *port,
+			     const struct videomode *vm);
+};
+
+struct display_entity_video_ops {
+	const struct display_entity_video_common_ops *common;
+	union {
+		const struct display_entity_video_dpi_ops *dpi;
+		const struct display_entity_video_dsi_ops *dsi;
+		const struct display_entity_video_dvi_ops *dvi;
+	};
+};
+
+/* -----------------------------------------------------------------------------
+ * Display Entity Control
+ */
+
+/**
+ * enum display_entity_state - State of a display entity
+ * @DISPLAY_ENTITY_STATE_OFF: The entity is turned off completely, possibly
+ *	including its power supplies. Communication with a display entity in
+ *	that state is not possible.
+ * @DISPLAY_ENTITY_STATE_STANDBY: The entity is in a low-power state. Full
+ *	communication with the display entity is supported, including pixel data
+ *	transfer, but the output is kept blanked.
+ * @DISPLAY_ENTITY_STATE_ON: The entity is fully operational.
+ */
+enum display_entity_state {
+	DISPLAY_ENTITY_STATE_OFF,
+	DISPLAY_ENTITY_STATE_STANDBY,
+	DISPLAY_ENTITY_STATE_ON,
+};
+
+enum display_entity_interface_type {
+	DISPLAY_ENTITY_INTERFACE_DPI,
+	DISPLAY_ENTITY_INTERFACE_DSI,
+	DISPLAY_ENTITY_INTERFACE_DVI,
+};
+
+struct display_entity_interface_params {
+	enum display_entity_interface_type type;
+	union {
+		struct mipi_dsi_interface_params dsi;
+	} u;
+};
+
+struct display_entity_control_ops {
+	int (*set_state)(struct display_entity *entity,
+			 enum display_entity_state state);
+	int (*update)(struct display_entity *entity);
+	int (*get_modes)(struct display_entity *entity,
+			 const struct videomode **modes);
+	int (*get_params)(struct display_entity *entity,
+			  struct display_entity_interface_params *params);
+	int (*get_size)(struct display_entity *entity,
+			unsigned int *width, unsigned int *height);
+};
+
+/* -----------------------------------------------------------------------------
+ * Display Entity
+ */
+
+/**
+ * struct display_entity - A display entity
+ * @list: list entry for entities list
+ * @dev: the owning device
+ * @owner: the owning module
+ * @name: the entity name
+ * @ref: reference count
+ * @release: entity refcount release function
+ * @port: array of data ports
+ * @num_ports: number of ports in the ports array
+ * @ops.ctrl: control operations, exposed to the entity user
+ * @ops.video: port-based video operations
+ * @source: video source port
+ * @state: display entity power state
+ */
+struct display_entity {
+	struct list_head list;
+	struct device *dev;
+	struct module *owner;
+	const char *name;
+	struct device_node *of_node;
+
+	struct kref ref;
+	void(*release)(struct display_entity *ent);
+
+	const char *source_name;
+	unsigned int source_port;
+	struct display_entity_port *source;
+
+	struct display_entity_port *ports;
+	unsigned int num_ports;
+
+	struct {
+		const struct display_entity_control_ops *ctrl;
+		const struct display_entity_video_ops *video;
+	} ops;
+
+	enum display_entity_state state;
+};
+
+struct display_entity *display_entity_get(struct display_entity *entity);
+void display_entity_put(struct display_entity *entity);
+
+int __must_check __display_entity_register(struct display_entity *entity,
+					   struct module *owner);
+void display_entity_unregister(struct display_entity *entity);
+
+#define display_entity_register(display_entity) \
+	__display_entity_register(display_entity, THIS_MODULE)
+
+/* -----------------------------------------------------------------------------
+ * Operation helpers
+ */
+
+/* Call a display entity operation, checking for NULL pointers along the way.
+ *
+ * Return -ENODEV if the port or its entity is NULL, -ENOIOCTLCMD if the
+ * operation isn't implemented by the entity, or the entity return value
+ * otherwise.
+ */
+#define display_entity_port_call(port, o, f, args...)			\
+	(!(port) || !(port)->entity ? -ENODEV :				\
+	 ((!(port)->entity->ops.video->o ||				\
+	   !(port)->entity->ops.video->o->f) ? -ENOIOCTLCMD :		\
+	  (port)->entity->ops.video->o->f((port) , ##args)))
+
+#define display_entity_call(entity, f, args...)				\
+	(!(entity) ? -ENODEV :						\
+	 (((entity)->ops.ctrl && (entity)->ops.ctrl->f) ?		\
+	  (entity)->ops.ctrl->f((entity) , ##args) : -ENOIOCTLCMD))
+
+int display_entity_set_state(struct display_entity *entity,
+			     enum display_entity_state state);
+int display_entity_update(struct display_entity *entity);
+int display_entity_get_modes(struct display_entity *entity,
+			     const struct videomode **modes);
+int display_entity_get_params(struct display_entity *entity,
+			      struct display_entity_interface_params *params);
+int display_entity_get_size(struct display_entity *entity,
+			    unsigned int *width, unsigned int *height);
+
+int display_entity_set_stream(struct display_entity_port *source,
+			      enum display_entity_stream_state state);
+
+#endif /* __DISPLAY_H__ */
