summary refs log tree commit diff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-08 18:09:33 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-08 18:09:33 -0700
commit9e9ac896667a55ae9a3df119611ee5322abe2890 (patch)
tree82d486ff50b822aff5691bd396247f8cbc1aa800
parent34b20e6df6970e36b93f445669ba5ef7a05fe01a (diff)
parente4e42b8ad24cabf4d6d3c20a63f18dd6b954d9c2 (diff)
downloadlinux-9e9ac896667a55ae9a3df119611ee5322abe2890.tar.gz
Merge tag 'fbdev-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux
Pull fbdev updates from Tomi Valkeinen:
 - much better HDMI infoframe support for OMAP
 - Cirrus Logic CLPS711X framebuffer driver
 - DT support for PL11x CLCD driver
 - various small fixes

* tag 'fbdev-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (35 commits)
  OMAPDSS: DSI: fix depopulating dsi peripherals
  video: hyperv: hyperv_fb: refresh the VM screen by force on VM panic
  video: ARM CLCD: Fix DT-related build problems
  drivers: video: fbdev: atmel_lcdfb.c: Add ability to inverted backlight PWM.
  video: ARM CLCD: Add DT support
  drm/omap: Add infoframe & dvi/hdmi mode support
  OMAPDSS: HDMI: remove the unused code
  OMAPDSS: HDMI5: add support to set infoframe & HDMI mode
  OMAPDSS: HDMI4: add support to set infoframe & HDMI mode
  OMAPDSS: HDMI: add infoframe and hdmi_dvi_mode fields
  OMAPDSS: add hdmi ops to hdmi-connector and tpd12s015
  OMAPDSS: add hdmi ops to hdmi_ops and omap_dss_driver
  OMAPDSS: HDMI: remove custom avi infoframe
  OMAPDSS: HDMI5: use common AVI infoframe support
  OMAPDSS: HDMI4: use common AVI infoframe support
  OMAPDSS: Kconfig: select HDMI
  OMAPDSS: HDMI: fix name conflict
  OMAPDSS: DISPC: clean up dispc_mgr_timings_ok
  OMAPDSS: DISPC: reject interlace for lcd out
  OMAPDSS: DISPC: fix debugfs reg dump
  ...
-rw-r--r--Documentation/devicetree/bindings/video/arm,pl11x.txt109
-rw-r--r--Documentation/devicetree/bindings/video/atmel,lcdc.txt1
-rw-r--r--Documentation/devicetree/bindings/video/cirrus,clps711x-fb.txt47
-rw-r--r--MAINTAINERS74
-rw-r--r--drivers/gpu/drm/omapdrm/omap_connector.c12
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.h1
-rw-r--r--drivers/gpu/drm/omapdrm/omap_encoder.c27
-rw-r--r--drivers/video/fbdev/68328fb.c8
-rw-r--r--drivers/video/fbdev/Kconfig23
-rw-r--r--drivers/video/fbdev/Makefile3
-rw-r--r--drivers/video/fbdev/amba-clcd.c263
-rw-r--r--drivers/video/fbdev/atmel_lcdfb.c3
-rw-r--r--drivers/video/fbdev/clps711x-fb.c397
-rw-r--r--drivers/video/fbdev/da8xx-fb.c9
-rw-r--r--drivers/video/fbdev/hyperv_fb.c62
-rw-r--r--drivers/video/fbdev/mbx/mbxfb.c4
-rw-r--r--drivers/video/fbdev/msm/mddi_client_dummy.c19
-rw-r--r--drivers/video/fbdev/omap2/displays-new/connector-hdmi.c19
-rw-r--r--drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c20
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c5
-rw-r--r--drivers/video/fbdev/omap2/dss/Kconfig1
-rw-r--r--drivers/video/fbdev/omap2/dss/dispc.c22
-rw-r--r--drivers/video/fbdev/omap2/dss/dsi.c9
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi.h107
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4.c53
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4_core.c164
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4_core.h1
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi5.c53
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi5_core.c124
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_common.c316
-rw-r--r--drivers/video/fbdev/s3c2410fb.c10
-rw-r--r--drivers/video/fbdev/sis/init.c2
-rw-r--r--drivers/video/fbdev/sis/sis_main.c4
-rw-r--r--include/linux/fb.h2
-rw-r--r--include/video/omapdss.h9
35 files changed, 1194 insertions, 789 deletions
diff --git a/Documentation/devicetree/bindings/video/arm,pl11x.txt b/Documentation/devicetree/bindings/video/arm,pl11x.txt
new file mode 100644
index 000000000000..3e3039a8a253
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/arm,pl11x.txt
@@ -0,0 +1,109 @@
+* ARM PrimeCell Color LCD Controller PL110/PL111
+
+See also Documentation/devicetree/bindings/arm/primecell.txt
+
+Required properties:
+
+- compatible: must be one of:
+	"arm,pl110", "arm,primecell"
+	"arm,pl111", "arm,primecell"
+
+- reg: base address and size of the control registers block
+
+- interrupt-names: either the single entry "combined" representing a
+	combined interrupt output (CLCDINTR), or the four entries
+	"mbe", "vcomp", "lnbu", "fuf" representing the individual
+	CLCDMBEINTR, CLCDVCOMPINTR, CLCDLNBUINTR, CLCDFUFINTR interrupts
+
+- interrupts: contains an interrupt specifier for each entry in
+	interrupt-names
+
+- clock-names: should contain "clcdclk" and "apb_pclk"
+
+- clocks: contains phandle and clock specifier pairs for the entries
+	in the clock-names property. See
+	Documentation/devicetree/binding/clock/clock-bindings.txt
+
+Optional properties:
+
+- memory-region: phandle to a node describing memory (see
+	Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt)
+	to be used for the framebuffer; if not present, the framebuffer
+	may be located anywhere in the memory
+
+- max-memory-bandwidth: maximum bandwidth in bytes per second that the
+	cell's memory interface can handle; if not present, the memory
+	interface is fast enough to handle all possible video modes
+
+Required sub-nodes:
+
+- port: describes LCD panel signals, following the common binding
+	for video transmitter interfaces; see
+	Documentation/devicetree/bindings/media/video-interfaces.txt;
+	when it is a TFT panel, the port's endpoint must define the
+	following property:
+
+	- arm,pl11x,tft-r0g0b0-pads: an array of three 32-bit values,
+		defining the way CLD pads are wired up; first value
+		contains index of the "CLD" external pin (pad) used
+		as R0 (first bit of the red component), second value
+	        index of the pad used as G0, third value index of the
+		pad used as B0, see also "LCD panel signal multiplexing
+		details" paragraphs in the PL110/PL111 Technical
+		Reference Manuals; this implicitly defines available
+		color modes, for example:
+		- PL111 TFT 4:4:4 panel:
+			arm,pl11x,tft-r0g0b0-pads = <4 15 20>;
+		- PL110 TFT (1:)5:5:5 panel:
+			arm,pl11x,tft-r0g0b0-pads = <1 7 13>;
+		- PL111 TFT (1:)5:5:5 panel:
+			arm,pl11x,tft-r0g0b0-pads = <3 11 19>;
+		- PL111 TFT 5:6:5 panel:
+			arm,pl11x,tft-r0g0b0-pads = <3 10 19>;
+		- PL110 and PL111 TFT 8:8:8 panel:
+			arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+		- PL110 and PL111 TFT 8:8:8 panel, R & B components swapped:
+			arm,pl11x,tft-r0g0b0-pads = <16 8 0>;
+
+
+Example:
+
+	clcd@10020000 {
+		compatible = "arm,pl111", "arm,primecell";
+		reg = <0x10020000 0x1000>;
+		interrupt-names = "combined";
+		interrupts = <0 44 4>;
+		clocks = <&oscclk1>, <&oscclk2>;
+		clock-names = "clcdclk", "apb_pclk";
+		max-memory-bandwidth = <94371840>; /* Bps, 1024x768@60 16bpp */
+
+		port {
+			clcd_pads: endpoint {
+				remote-endpoint = <&clcd_panel>;
+				arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
+			};
+		};
+
+	};
+
+	panel {
+		compatible = "panel-dpi";
+
+		port {
+			clcd_panel: endpoint {
+				remote-endpoint = <&clcd_pads>;
+			};
+		};
+
+		panel-timing {
+			clock-frequency = <25175000>;
+			hactive = <640>;
+			hback-porch = <40>;
+			hfront-porch = <24>;
+			hsync-len = <96>;
+			vactive = <480>;
+			vback-porch = <32>;
+			vfront-porch = <11>;
+			vsync-len = <2>;
+		};
+	};
diff --git a/Documentation/devicetree/bindings/video/atmel,lcdc.txt b/Documentation/devicetree/bindings/video/atmel,lcdc.txt
index 1ec175eddca8..b75af94a5e52 100644
--- a/Documentation/devicetree/bindings/video/atmel,lcdc.txt
+++ b/Documentation/devicetree/bindings/video/atmel,lcdc.txt
@@ -46,6 +46,7 @@ Required properties (as per of_videomode_helper):
 
 Optional properties (as per of_videomode_helper):
  - atmel,lcdcon-backlight: enable backlight
+ - atmel,lcdcon-backlight-inverted: invert backlight PWM polarity
  - atmel,lcd-wiring-mode: lcd wiring mode "RGB" or "BRG"
  - atmel,power-control-gpio: gpio to power on or off the LCD (as many as needed)
 
diff --git a/Documentation/devicetree/bindings/video/cirrus,clps711x-fb.txt b/Documentation/devicetree/bindings/video/cirrus,clps711x-fb.txt
new file mode 100644
index 000000000000..6fc3c6adeefa
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/cirrus,clps711x-fb.txt
@@ -0,0 +1,47 @@
+* Currus Logic CLPS711X Framebuffer
+
+Required properties:
+- compatible: Shall contain "cirrus,clps711x-fb".
+- reg       : Physical base address and length of the controller's registers +
+              location and size of the framebuffer memory.
+- clocks    : phandle + clock specifier pair of the FB reference clock.
+- display   : phandle to a display node as described in
+              Documentation/devicetree/bindings/video/display-timing.txt.
+              Additionally, the display node has to define properties:
+  - bits-per-pixel: Bits per pixel.
+  - ac-prescale   : LCD AC bias frequency. This frequency is the required
+                    AC bias frequency for a given manufacturer's LCD plate.
+  - cmap-invert   : Invert the color levels (Optional).
+
+Optional properties:
+- lcd-supply: Regulator for LCD supply voltage.
+
+Example:
+	fb: fb@800002c0 {
+		compatible = "cirrus,ep7312-fb", "cirrus,clps711x-fb";
+		reg = <0x800002c0 0xd44>, <0x60000000 0xc000>;
+		clocks = <&clks 2>;
+		lcd-supply = <&reg5v0>;
+		display = <&display>;
+	};
+
+	display: display {
+		model = "320x240x4";
+		native-mode = <&timing0>;
+		bits-per-pixel = <4>;
+		ac-prescale = <17>;
+
+		display-timings {
+			timing0: 320x240 {
+				hactive = <320>;
+				hback-porch = <0>;
+				hfront-porch = <0>;
+				hsync-len = <0>;
+				vactive = <240>;
+				vback-porch = <0>;
+				vfront-porch = <0>;
+				vsync-len = <0>;
+				clock-frequency = <6500000>;
+			};
+		};
+	};
diff --git a/MAINTAINERS b/MAINTAINERS
index a0abe7c1a8ea..7e2eb4c646e3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -606,7 +606,7 @@ W:	http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_
 S:	Supported
 F:	drivers/char/hw_random/geode-rng.c
 F:	drivers/crypto/geode*
-F:	drivers/video/geode/
+F:	drivers/video/fbdev/geode/
 F:	arch/x86/include/asm/geode.h
 
 AMD IOMMU (AMD-VI)
@@ -735,8 +735,8 @@ F:	drivers/ata/pata_arasan_cf.c
 ARC FRAMEBUFFER DRIVER
 M:	Jaya Kumar <jayalk@intworks.biz>
 S:	Maintained
-F:	drivers/video/arcfb.c
-F:	drivers/video/fb_defio.c
+F:	drivers/video/fbdev/arcfb.c
+F:	drivers/video/fbdev/core/fb_defio.c
 
 ARM MFM AND FLOPPY DRIVERS
 M:	Ian Molton <spyro@f2s.com>
@@ -775,7 +775,7 @@ F:	sound/arm/aaci.*
 ARM PRIMECELL CLCD PL110 DRIVER
 M:	Russell King <linux@arm.linux.org.uk>
 S:	Maintained
-F:	drivers/video/amba-clcd.*
+F:	drivers/video/fbdev/amba-clcd.*
 
 ARM PRIMECELL KMI PL050 DRIVER
 M:	Russell King <linux@arm.linux.org.uk>
@@ -1180,7 +1180,7 @@ M:	Daniel Walker <dwalker@fifo99.com>
 M:	Bryan Huntsman <bryanh@codeaurora.org>
 L:	linux-arm-msm@vger.kernel.org
 F:	arch/arm/mach-msm/
-F:	drivers/video/msm/
+F:	drivers/video/fbdev/msm/
 F:	drivers/mmc/host/msm_sdcc.c
 F:	drivers/mmc/host/msm_sdcc.h
 F:	drivers/tty/serial/msm_serial.h
@@ -1414,7 +1414,7 @@ F:	drivers/mtd/nand/nuc900_nand.c
 F:	drivers/rtc/rtc-nuc900.c
 F:	drivers/spi/spi-nuc900.c
 F:	drivers/usb/host/ehci-w90x900.c
-F:	drivers/video/nuc900fb.c
+F:	drivers/video/fbdev/nuc900fb.c
 
 ARM/U300 MACHINE SUPPORT
 M:	Linus Walleij <linus.walleij@linaro.org>
@@ -1484,9 +1484,9 @@ F:	drivers/rtc/rtc-vt8500.c
 F:	drivers/tty/serial/vt8500_serial.c
 F:	drivers/usb/host/ehci-platform.c
 F:	drivers/usb/host/uhci-platform.c
-F:	drivers/video/vt8500lcdfb.*
-F:	drivers/video/wm8505fb*
-F:	drivers/video/wmt_ge_rops.*
+F:	drivers/video/fbdev/vt8500lcdfb.*
+F:	drivers/video/fbdev/wm8505fb*
+F:	drivers/video/fbdev/wmt_ge_rops.*
 
 ARM/ZIPIT Z2 SUPPORT
 M:	Marek Vasut <marek.vasut@gmail.com>
@@ -1676,7 +1676,7 @@ ATMEL LCDFB DRIVER
 M:	Nicolas Ferre <nicolas.ferre@atmel.com>
 L:	linux-fbdev@vger.kernel.org
 S:	Maintained
-F:	drivers/video/atmel_lcdfb.c
+F:	drivers/video/fbdev/atmel_lcdfb.c
 F:	include/video/atmel_lcdc.h
 
 ATMEL MACB ETHERNET DRIVER
@@ -2703,7 +2703,7 @@ M:	Russell King <linux@arm.linux.org.uk>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:	http://www.arm.linux.org.uk/
 S:	Maintained
-F:	drivers/video/cyber2000fb.*
+F:	drivers/video/fbdev/cyber2000fb.*
 
 CYCLADES ASYNC MUX DRIVER
 W:	http://www.cyclades.com/
@@ -2941,7 +2941,7 @@ M:	Bernie Thompson <bernie@plugable.com>
 L:	linux-fbdev@vger.kernel.org
 S:	Maintained
 W:	http://plugable.com/category/projects/udlfb/
-F:	drivers/video/udlfb.c
+F:	drivers/video/fbdev/udlfb.c
 F:	include/video/udlfb.h
 F:	Documentation/fb/udlfb.txt
 
@@ -3452,7 +3452,7 @@ EFIFB FRAMEBUFFER DRIVER
 L:	linux-fbdev@vger.kernel.org
 M:	Peter Jones <pjones@redhat.com>
 S:	Maintained
-F:	drivers/video/efifb.c
+F:	drivers/video/fbdev/efifb.c
 
 EFS FILESYSTEM
 W:	http://aeschi.ch.eu.org/efs/
@@ -3517,7 +3517,7 @@ EPSON S1D13XXX FRAMEBUFFER DRIVER
 M:	Kristoffer Ericson <kristoffer.ericson@gmail.com>
 S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git
-F:	drivers/video/s1d13xxxfb.c
+F:	drivers/video/fbdev/s1d13xxxfb.c
 F:	include/video/s1d13xxxfb.h
 
 ETHERNET BRIDGE
@@ -3595,7 +3595,7 @@ M:	Donghwa Lee <dh09.lee@samsung.com>
 M:	Kyungmin Park <kyungmin.park@samsung.com>
 L:	linux-fbdev@vger.kernel.org
 S:	Maintained
-F:	drivers/video/exynos/exynos_mipi*
+F:	drivers/video/fbdev/exynos/exynos_mipi*
 F:	include/video/exynos_mipi*
 
 F71805F HARDWARE MONITORING DRIVER
@@ -3774,7 +3774,7 @@ FREESCALE DIU FRAMEBUFFER DRIVER
 M:	Timur Tabi <timur@tabi.org>
 L:	linux-fbdev@vger.kernel.org
 S:	Maintained
-F:	drivers/video/fsl-diu-fb.*
+F:	drivers/video/fbdev/fsl-diu-fb.*
 
 FREESCALE DMA DRIVER
 M:	Li Yang <leoli@freescale.com>
@@ -3796,7 +3796,7 @@ L:	linux-fbdev@vger.kernel.org
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 F:	include/linux/platform_data/video-imxfb.h
-F:	drivers/video/imxfb.c
+F:	drivers/video/fbdev/imxfb.c
 
 FREESCALE SOC FS_ENET DRIVER
 M:	Pantelis Antoniou <pantelis.antoniou@gmail.com>
@@ -4222,7 +4222,7 @@ M:	Ferenc Bakonyi <fero@drama.obuda.kando.hu>
 L:	linux-nvidia@lists.surfsouth.com
 W:	http://drama.obuda.kando.hu/~fero/cgi-bin/hgafb.shtml
 S:	Maintained
-F:	drivers/video/hgafb.c
+F:	drivers/video/fbdev/hgafb.c
 
 HIBERNATION (aka Software Suspend, aka swsusp)
 M:	"Rafael J. Wysocki" <rjw@rjwysocki.net>
@@ -4364,7 +4364,7 @@ F:	drivers/hv/
 F:	drivers/input/serio/hyperv-keyboard.c
 F:	drivers/net/hyperv/
 F:	drivers/scsi/storvsc_drv.c
-F:	drivers/video/hyperv_fb.c
+F:	drivers/video/fbdev/hyperv_fb.c
 F:	include/linux/hyperv.h
 F:	tools/hv/
 
@@ -4620,7 +4620,7 @@ F:	security/integrity/ima/
 IMS TWINTURBO FRAMEBUFFER DRIVER
 L:	linux-fbdev@vger.kernel.org
 S:	Orphan
-F:	drivers/video/imsttfb.c
+F:	drivers/video/fbdev/imsttfb.c
 
 INFINIBAND SUBSYSTEM
 M:	Roland Dreier <roland@kernel.org>
@@ -4687,13 +4687,13 @@ M:	Maik Broemme <mbroemme@plusserver.de>
 L:	linux-fbdev@vger.kernel.org
 S:	Maintained
 F:	Documentation/fb/intelfb.txt
-F:	drivers/video/intelfb/
+F:	drivers/video/fbdev/intelfb/
 
 INTEL 810/815 FRAMEBUFFER DRIVER
 M:	Antonino Daplas <adaplas@gmail.com>
 L:	linux-fbdev@vger.kernel.org
 S:	Maintained
-F:	drivers/video/i810/
+F:	drivers/video/fbdev/i810/
 
 INTEL MENLOW THERMAL DRIVER
 M:	Sujith Thomas <sujith.thomas@intel.com>
@@ -5758,7 +5758,7 @@ F:	drivers/mmc/host/mvsdio.*
 MATROX FRAMEBUFFER DRIVER
 L:	linux-fbdev@vger.kernel.org
 S:	Orphan
-F:	drivers/video/matrox/matroxfb_*
+F:	drivers/video/fbdev/matrox/matroxfb_*
 F:	include/uapi/linux/matroxfb.h
 
 MAX16065 HARDWARE MONITOR DRIVER
@@ -6398,8 +6398,8 @@ NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER
 M:	Antonino Daplas <adaplas@gmail.com>
 L:	linux-fbdev@vger.kernel.org
 S:	Maintained
-F:	drivers/video/riva/
-F:	drivers/video/nvidia/
+F:	drivers/video/fbdev/riva/
+F:	drivers/video/fbdev/nvidia/
 
 NVM EXPRESS DRIVER
 M:	Matthew Wilcox <willy@linux.intel.com>
@@ -6469,14 +6469,14 @@ M:	Tomi Valkeinen <tomi.valkeinen@ti.com>
 L:	linux-fbdev@vger.kernel.org
 L:	linux-omap@vger.kernel.org
 S:	Maintained
-F:	drivers/video/omap/
+F:	drivers/video/fbdev/omap/
 
 OMAP DISPLAY SUBSYSTEM and FRAMEBUFFER SUPPORT (DSS2)
 M:	Tomi Valkeinen <tomi.valkeinen@ti.com>
 L:	linux-omap@vger.kernel.org
 L:	linux-fbdev@vger.kernel.org
 S:	Maintained
-F:	drivers/video/omap2/
+F:	drivers/video/fbdev/omap2/
 F:	Documentation/arm/OMAP/DSS
 
 OMAP HARDWARE SPINLOCK SUPPORT
@@ -6768,7 +6768,7 @@ F:	drivers/char/agp/parisc-agp.c
 F:	drivers/input/serio/gscps2.c
 F:	drivers/parport/parport_gsc.*
 F:	drivers/tty/serial/8250/8250_gsc.c
-F:	drivers/video/sti*
+F:	drivers/video/fbdev/sti*
 F:	drivers/video/console/sti*
 F:	drivers/video/logo/logo_parisc*
 
@@ -7027,7 +7027,7 @@ S:	Maintained
 T:	git git://github.com/gxt/linux.git
 F:	drivers/input/serio/i8042-unicore32io.h
 F:	drivers/i2c/busses/i2c-puv3.c
-F:	drivers/video/fb-puv3.c
+F:	drivers/video/fbdev/fb-puv3.c
 F:	drivers/rtc/rtc-puv3.c
 
 PMBUS HARDWARE MONITORING DRIVERS
@@ -7407,7 +7407,7 @@ RADEON FRAMEBUFFER DISPLAY DRIVER
 M:	Benjamin Herrenschmidt <benh@kernel.crashing.org>
 L:	linux-fbdev@vger.kernel.org
 S:	Maintained
-F:	drivers/video/aty/radeon*
+F:	drivers/video/fbdev/aty/radeon*
 F:	include/uapi/linux/radeonfb.h
 
 RADIOSHARK RADIO DRIVER
@@ -7429,7 +7429,7 @@ RAGE128 FRAMEBUFFER DISPLAY DRIVER
 M:	Paul Mackerras <paulus@samba.org>
 L:	linux-fbdev@vger.kernel.org
 S:	Maintained
-F:	drivers/video/aty/aty128fb.c
+F:	drivers/video/fbdev/aty/aty128fb.c
 
 RALINK RT2X00 WIRELESS LAN DRIVER
 P:	rt2x00 project
@@ -7677,7 +7677,7 @@ S3 SAVAGE FRAMEBUFFER DRIVER
 M:	Antonino Daplas <adaplas@gmail.com>
 L:	linux-fbdev@vger.kernel.org
 S:	Maintained
-F:	drivers/video/savage/
+F:	drivers/video/fbdev/savage/
 
 S390
 M:	Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -7800,7 +7800,7 @@ SAMSUNG FRAMEBUFFER DRIVER
 M:	Jingoo Han <jg1.han@samsung.com>
 L:	linux-fbdev@vger.kernel.org
 S:	Maintained
-F:	drivers/video/s3c-fb.c
+F:	drivers/video/fbdev/s3c-fb.c
 
 SAMSUNG MULTIFUNCTION DEVICE DRIVERS
 M:	Sangbeom Kim <sbkim73@samsung.com>
@@ -8297,7 +8297,7 @@ M:	Thomas Winischhofer <thomas@winischhofer.net>
 W:	http://www.winischhofer.net/linuxsisvga.shtml
 S:	Maintained
 F:	Documentation/fb/sisfb.txt
-F:	drivers/video/sis/
+F:	drivers/video/fbdev/sis/
 F:	include/video/sisfb.h
 
 SIS USB2VGA DRIVER
@@ -8406,7 +8406,7 @@ SMSC UFX6000 and UFX7000 USB to VGA DRIVER
 M:	Steve Glendinning <steve.glendinning@shawell.net>
 L:	linux-fbdev@vger.kernel.org
 S:	Maintained
-F:	drivers/video/smscufx.c
+F:	drivers/video/fbdev/smscufx.c
 
 SOC-CAMERA V4L2 SUBSYSTEM
 M:	Guennadi Liakhovetski <g.liakhovetski@gmx.de>
@@ -9670,7 +9670,7 @@ L:	linux-fbdev@vger.kernel.org
 W:	http://dev.gentoo.org/~spock/projects/uvesafb/
 S:	Maintained
 F:	Documentation/fb/uvesafb.txt
-F:	drivers/video/uvesafb.*
+F:	drivers/video/fbdev/uvesafb.*
 
 VFAT/FAT/MSDOS FILESYSTEM
 M:	OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
@@ -9743,7 +9743,7 @@ S:	Maintained
 F:	include/linux/via-core.h
 F:	include/linux/via-gpio.h
 F:	include/linux/via_i2c.h
-F:	drivers/video/via/
+F:	drivers/video/fbdev/via/
 
 VIA VELOCITY NETWORK DRIVER
 M:	Francois Romieu <romieu@fr.zoreil.com>
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index 36bc5cc80816..a94b11f7859d 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -32,8 +32,16 @@ struct omap_connector {
 	struct drm_connector base;
 	struct omap_dss_device *dssdev;
 	struct drm_encoder *encoder;
+	bool hdmi_mode;
 };
 
+bool omap_connector_get_hdmi_mode(struct drm_connector *connector)
+{
+	struct omap_connector *omap_connector = to_omap_connector(connector);
+
+	return omap_connector->hdmi_mode;
+}
+
 void copy_timings_omap_to_drm(struct drm_display_mode *mode,
 		struct omap_video_timings *timings)
 {
@@ -162,10 +170,14 @@ static int omap_connector_get_modes(struct drm_connector *connector)
 			drm_mode_connector_update_edid_property(
 					connector, edid);
 			n = drm_add_edid_modes(connector, edid);
+
+			omap_connector->hdmi_mode =
+				drm_detect_hdmi_monitor(edid);
 		} else {
 			drm_mode_connector_update_edid_property(
 					connector, NULL);
 		}
+
 		kfree(edid);
 	} else {
 		struct drm_display_mode *mode = drm_mode_create(dev);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index b08a450d1b5d..84d73a61b34b 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -187,6 +187,7 @@ struct drm_encoder *omap_connector_attached_encoder(
 		struct drm_connector *connector);
 void omap_connector_flush(struct drm_connector *connector,
 		int x, int y, int w, int h);
+bool omap_connector_get_hdmi_mode(struct drm_connector *connector);
 
 void copy_timings_omap_to_drm(struct drm_display_mode *mode,
 		struct omap_video_timings *timings);
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 5290a88c681d..7445fb1491ae 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -17,6 +17,8 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <drm/drm_edid.h>
+
 #include "omap_drv.h"
 
 #include "drm_crtc.h"
@@ -89,6 +91,31 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder,
 				struct drm_display_mode *mode,
 				struct drm_display_mode *adjusted_mode)
 {
+	struct drm_device *dev = encoder->dev;
+	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
+	struct omap_dss_device *dssdev = omap_encoder->dssdev;
+	struct drm_connector *connector;
+	bool hdmi_mode;
+	int r;
+
+	hdmi_mode = false;
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		if (connector->encoder == encoder) {
+			hdmi_mode = omap_connector_get_hdmi_mode(connector);
+			break;
+		}
+	}
+
+	if (dssdev->driver->set_hdmi_mode)
+		dssdev->driver->set_hdmi_mode(dssdev, hdmi_mode);
+
+	if (hdmi_mode && dssdev->driver->set_hdmi_infoframe) {
+		struct hdmi_avi_infoframe avi;
+
+		r = drm_hdmi_avi_infoframe_from_display_mode(&avi, adjusted_mode);
+		if (r == 0)
+			dssdev->driver->set_hdmi_infoframe(dssdev, &avi);
+	}
 }
 
 static void omap_encoder_prepare(struct drm_encoder *encoder)
diff --git a/drivers/video/fbdev/68328fb.c b/drivers/video/fbdev/68328fb.c
index 552258c8f99d..17f21cedff9b 100644
--- a/drivers/video/fbdev/68328fb.c
+++ b/drivers/video/fbdev/68328fb.c
@@ -49,12 +49,6 @@
 #error wrong architecture for the MC68x328 frame buffer device
 #endif
 
-#if defined(CONFIG_FB_68328_INVERT)
-#define MC68X328FB_MONO_VISUAL FB_VISUAL_MONO01
-#else
-#define MC68X328FB_MONO_VISUAL FB_VISUAL_MONO10
-#endif
-
 static u_long videomemory;
 static u_long videomemorysize;
 
@@ -462,7 +456,7 @@ int __init mc68x328fb_init(void)
 	fb_info.fix.line_length =
 		get_line_length(mc68x328fb_default.xres_virtual, mc68x328fb_default.bits_per_pixel);
 	fb_info.fix.visual = (mc68x328fb_default.bits_per_pixel) == 1 ?
-		MC68X328FB_MONO_VISUAL : FB_VISUAL_PSEUDOCOLOR;
+		FB_VISUAL_MONO10 : FB_VISUAL_PSEUDOCOLOR;
 	if (fb_info.var.bits_per_pixel == 1) {
 		fb_info.var.red.length = fb_info.var.green.length = fb_info.var.blue.length = 1;
 		fb_info.var.red.offset = fb_info.var.green.offset = fb_info.var.blue.offset = 0;
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index e05a58d759be..e911b9c96e19 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -280,6 +280,8 @@ config FB_ARMCLCD
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
+	select FB_MODE_HELPERS if OF
+	select VIDEOMODE_HELPERS if OF
 	help
 	  This framebuffer device driver is for the ARM PrimeCell PL110
 	  Colour LCD controller.  ARM PrimeCells provide the building
@@ -307,15 +309,26 @@ config FB_ACORN
 	  hardware found in Acorn RISC PCs and other ARM-based machines.  If
 	  unsure, say N.
 
-config FB_CLPS711X
-	bool "CLPS711X LCD support"
-	depends on (FB = y) && ARM && ARCH_CLPS711X
+config FB_CLPS711X_OLD
+	tristate
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
+
+config FB_CLPS711X
+	tristate "CLPS711X LCD support"
+	depends on FB && (ARCH_CLPS711X || COMPILE_TEST)
+	select FB_CLPS711X_OLD if ARCH_CLPS711X && !ARCH_MULTIPLATFORM
+	select BACKLIGHT_LCD_SUPPORT
+	select FB_MODE_HELPERS
+	select FB_SYS_FILLRECT
+	select FB_SYS_COPYAREA
+	select FB_SYS_IMAGEBLIT
+	select LCD_CLASS_DEVICE
+	select VIDEOMODE_HELPERS
 	help
-	  Say Y to enable the Framebuffer driver for the CLPS7111 and
-	  EP7212 processors.
+	  Say Y to enable the Framebuffer driver for the Cirrus Logic
+	  CLPS711X CPUs.
 
 config FB_SA1100
 	bool "SA-1100 LCD support"
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 0b2090d2e52e..1979afffccfe 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -14,7 +14,8 @@ obj-$(CONFIG_FB_WMT_GE_ROPS)   += wmt_ge_rops.o
 # Hardware specific drivers go first
 obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p_planar.o
 obj-$(CONFIG_FB_ARC)              += arcfb.o
-obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o
+obj-$(CONFIG_FB_CLPS711X)	  += clps711x-fb.o
+obj-$(CONFIG_FB_CLPS711X_OLD)	  += clps711xfb.o
 obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o
 obj-$(CONFIG_FB_GRVGA)            += grvga.o
 obj-$(CONFIG_FB_PM2)              += pm2fb.o
diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c
index 14d6b3793e0a..beadd3edaa17 100644
--- a/drivers/video/fbdev/amba-clcd.c
+++ b/drivers/video/fbdev/amba-clcd.c
@@ -26,6 +26,13 @@
 #include <linux/amba/clcd.h>
 #include <linux/clk.h>
 #include <linux/hardirq.h>
+#include <linux/dma-mapping.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_graph.h>
+#include <video/display_timing.h>
+#include <video/of_display_timing.h>
+#include <video/videomode.h>
 
 #include <asm/sizes.h>
 
@@ -543,6 +550,259 @@ static int clcdfb_register(struct clcd_fb *fb)
 	return ret;
 }
 
+#ifdef CONFIG_OF
+static int clcdfb_of_get_dpi_panel_mode(struct device_node *node,
+		struct fb_videomode *mode)
+{
+	int err;
+	struct display_timing timing;
+	struct videomode video;
+
+	err = of_get_display_timing(node, "panel-timing", &timing);
+	if (err)
+		return err;
+
+	videomode_from_timing(&timing, &video);
+
+	err = fb_videomode_from_videomode(&video, mode);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int clcdfb_snprintf_mode(char *buf, int size, struct fb_videomode *mode)
+{
+	return snprintf(buf, size, "%ux%u@%u", mode->xres, mode->yres,
+			mode->refresh);
+}
+
+static int clcdfb_of_get_mode(struct device *dev, struct device_node *endpoint,
+		struct fb_videomode *mode)
+{
+	int err;
+	struct device_node *panel;
+	char *name;
+	int len;
+
+	panel = of_graph_get_remote_port_parent(endpoint);
+	if (!panel)
+		return -ENODEV;
+
+	/* Only directly connected DPI panels supported for now */
+	if (of_device_is_compatible(panel, "panel-dpi"))
+		err = clcdfb_of_get_dpi_panel_mode(panel, mode);
+	else
+		err = -ENOENT;
+	if (err)
+		return err;
+
+	len = clcdfb_snprintf_mode(NULL, 0, mode);
+	name = devm_kzalloc(dev, len + 1, GFP_KERNEL);
+	clcdfb_snprintf_mode(name, len + 1, mode);
+	mode->name = name;
+
+	return 0;
+}
+
+static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0)
+{
+	static struct {
+		unsigned int part;
+		u32 r0, g0, b0;
+		u32 caps;
+	} panels[] = {
+		{ 0x110, 1,  7, 13, CLCD_CAP_5551 },
+		{ 0x110, 0,  8, 16, CLCD_CAP_888 },
+		{ 0x111, 4, 14, 20, CLCD_CAP_444 },
+		{ 0x111, 3, 11, 19, CLCD_CAP_444 | CLCD_CAP_5551 },
+		{ 0x111, 3, 10, 19, CLCD_CAP_444 | CLCD_CAP_5551 |
+				    CLCD_CAP_565 },
+		{ 0x111, 0,  8, 16, CLCD_CAP_444 | CLCD_CAP_5551 |
+				    CLCD_CAP_565 | CLCD_CAP_888 },
+	};
+	int i;
+
+	/* Bypass pixel clock divider, data output on the falling edge */
+	fb->panel->tim2 = TIM2_BCD | TIM2_IPC;
+
+	/* TFT display, vert. comp. interrupt at the start of the back porch */
+	fb->panel->cntl |= CNTL_LCDTFT | CNTL_LCDVCOMP(1);
+
+	fb->panel->caps = 0;
+
+	/* Match the setup with known variants */
+	for (i = 0; i < ARRAY_SIZE(panels) && !fb->panel->caps; i++) {
+		if (amba_part(fb->dev) != panels[i].part)
+			continue;
+		if (g0 != panels[i].g0)
+			continue;
+		if (r0 == panels[i].r0 && b0 == panels[i].b0)
+			fb->panel->caps = panels[i].caps & CLCD_CAP_RGB;
+		if (r0 == panels[i].b0 && b0 == panels[i].r0)
+			fb->panel->caps = panels[i].caps & CLCD_CAP_BGR;
+	}
+
+	return fb->panel->caps ? 0 : -EINVAL;
+}
+
+static int clcdfb_of_init_display(struct clcd_fb *fb)
+{
+	struct device_node *endpoint;
+	int err;
+	u32 max_bandwidth;
+	u32 tft_r0b0g0[3];
+
+	fb->panel = devm_kzalloc(&fb->dev->dev, sizeof(*fb->panel), GFP_KERNEL);
+	if (!fb->panel)
+		return -ENOMEM;
+
+	endpoint = of_graph_get_next_endpoint(fb->dev->dev.of_node, NULL);
+	if (!endpoint)
+		return -ENODEV;
+
+	err = clcdfb_of_get_mode(&fb->dev->dev, endpoint, &fb->panel->mode);
+	if (err)
+		return err;
+
+	err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth",
+			&max_bandwidth);
+	if (!err)
+		fb->panel->bpp = 8 * max_bandwidth / (fb->panel->mode.xres *
+				fb->panel->mode.yres * fb->panel->mode.refresh);
+	else
+		fb->panel->bpp = 32;
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	fb->panel->cntl |= CNTL_BEBO;
+#endif
+	fb->panel->width = -1;
+	fb->panel->height = -1;
+
+	if (of_property_read_u32_array(endpoint,
+			"arm,pl11x,tft-r0g0b0-pads",
+			tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) == 0)
+		return clcdfb_of_init_tft_panel(fb, tft_r0b0g0[0],
+				 tft_r0b0g0[1],  tft_r0b0g0[2]);
+
+	return -ENOENT;
+}
+
+static int clcdfb_of_vram_setup(struct clcd_fb *fb)
+{
+	int err;
+	struct device_node *memory;
+	u64 size;
+
+	err = clcdfb_of_init_display(fb);
+	if (err)
+		return err;
+
+	memory = of_parse_phandle(fb->dev->dev.of_node, "memory-region", 0);
+	if (!memory)
+		return -ENODEV;
+
+	fb->fb.screen_base = of_iomap(memory, 0);
+	if (!fb->fb.screen_base)
+		return -ENOMEM;
+
+	fb->fb.fix.smem_start = of_translate_address(memory,
+			of_get_address(memory, 0, &size, NULL));
+	fb->fb.fix.smem_len = size;
+
+	return 0;
+}
+
+static int clcdfb_of_vram_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+	unsigned long off, user_size, kernel_size;
+
+
+	off = vma->vm_pgoff << PAGE_SHIFT;
+	user_size = vma->vm_end - vma->vm_start;
+	kernel_size = fb->fb.fix.smem_len;
+
+	if (off >= kernel_size || user_size > (kernel_size - off))
+		return -ENXIO;
+
+	return remap_pfn_range(vma, vma->vm_start,
+			__phys_to_pfn(fb->fb.fix.smem_start) + vma->vm_pgoff,
+			user_size,
+			pgprot_writecombine(vma->vm_page_prot));
+}
+
+static void clcdfb_of_vram_remove(struct clcd_fb *fb)
+{
+	iounmap(fb->fb.screen_base);
+}
+
+static int clcdfb_of_dma_setup(struct clcd_fb *fb)
+{
+	unsigned long framesize;
+	dma_addr_t dma;
+	int err;
+
+	err = clcdfb_of_init_display(fb);
+	if (err)
+		return err;
+
+	framesize = fb->panel->mode.xres * fb->panel->mode.yres *
+			fb->panel->bpp / 8;
+	fb->fb.screen_base = dma_alloc_coherent(&fb->dev->dev, framesize,
+			&dma, GFP_KERNEL);
+	if (!fb->fb.screen_base)
+		return -ENOMEM;
+
+	fb->fb.fix.smem_start = dma;
+	fb->fb.fix.smem_len = framesize;
+
+	return 0;
+}
+
+static int clcdfb_of_dma_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+	return dma_mmap_writecombine(&fb->dev->dev, vma, fb->fb.screen_base,
+			fb->fb.fix.smem_start, fb->fb.fix.smem_len);
+}
+
+static void clcdfb_of_dma_remove(struct clcd_fb *fb)
+{
+	dma_free_coherent(&fb->dev->dev, fb->fb.fix.smem_len,
+			fb->fb.screen_base, fb->fb.fix.smem_start);
+}
+
+static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev)
+{
+	struct clcd_board *board = devm_kzalloc(&dev->dev, sizeof(*board),
+			GFP_KERNEL);
+	struct device_node *node = dev->dev.of_node;
+
+	if (!board)
+		return NULL;
+
+	board->name = of_node_full_name(node);
+	board->caps = CLCD_CAP_ALL;
+	board->check = clcdfb_check;
+	board->decode = clcdfb_decode;
+	if (of_find_property(node, "memory-region", NULL)) {
+		board->setup = clcdfb_of_vram_setup;
+		board->mmap = clcdfb_of_vram_mmap;
+		board->remove = clcdfb_of_vram_remove;
+	} else {
+		board->setup = clcdfb_of_dma_setup;
+		board->mmap = clcdfb_of_dma_mmap;
+		board->remove = clcdfb_of_dma_remove;
+	}
+
+	return board;
+}
+#else
+static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev)
+{
+	return NULL;
+}
+#endif
+
 static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
 {
 	struct clcd_board *board = dev_get_platdata(&dev->dev);
@@ -550,6 +810,9 @@ static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
 	int ret;
 
 	if (!board)
+		board = clcdfb_of_get_board(dev);
+
+	if (!board)
 		return -EINVAL;
 
 	ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c
index d36e830d6fc6..92640d46770a 100644
--- a/drivers/video/fbdev/atmel_lcdfb.c
+++ b/drivers/video/fbdev/atmel_lcdfb.c
@@ -290,7 +290,7 @@ static void init_contrast(struct atmel_lcdfb_info *sinfo)
 
 	/* contrast pwm can be 'inverted' */
 	if (pdata->lcdcon_pol_negative)
-			contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE);
+		contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE);
 
 	/* have some default contrast/backlight settings */
 	lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);
@@ -1097,6 +1097,7 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
 	pdata->lcd_wiring_mode = ret;
 
 	pdata->lcdcon_is_backlight = of_property_read_bool(display_np, "atmel,lcdcon-backlight");
+	pdata->lcdcon_pol_negative = of_property_read_bool(display_np, "atmel,lcdcon-backlight-inverted");
 
 	timings = of_get_display_timings(display_np);
 	if (!timings) {
diff --git a/drivers/video/fbdev/clps711x-fb.c b/drivers/video/fbdev/clps711x-fb.c
new file mode 100644
index 000000000000..49a7bb4ef02f
--- /dev/null
+++ b/drivers/video/fbdev/clps711x-fb.c
@@ -0,0 +1,397 @@
+/*
+ * Cirrus Logic CLPS711X FB driver
+ *
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ * Based on driver by Russell King <rmk@arm.linux.org.uk>
+ *
+ * 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/fb.h>
+#include <linux/io.h>
+#include <linux/lcd.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/clps711x.h>
+#include <linux/regulator/consumer.h>
+#include <video/of_display_timing.h>
+
+#define CLPS711X_FB_NAME	"clps711x-fb"
+#define CLPS711X_FB_BPP_MAX	(4)
+
+/* Registers relative to LCDCON */
+#define CLPS711X_LCDCON		(0x0000)
+# define LCDCON_GSEN		BIT(30)
+# define LCDCON_GSMD		BIT(31)
+#define CLPS711X_PALLSW		(0x0280)
+#define CLPS711X_PALMSW		(0x02c0)
+#define CLPS711X_FBADDR		(0x0d40)
+
+struct clps711x_fb_info {
+	struct clk		*clk;
+	void __iomem		*base;
+	struct regmap		*syscon;
+	resource_size_t		buffsize;
+	struct fb_videomode	mode;
+	struct regulator	*lcd_pwr;
+	u32			ac_prescale;
+	bool			cmap_invert;
+};
+
+static int clps711x_fb_setcolreg(u_int regno, u_int red, u_int green,
+				 u_int blue, u_int transp, struct fb_info *info)
+{
+	struct clps711x_fb_info *cfb = info->par;
+	u32 level, mask, shift;
+
+	if (regno >= BIT(info->var.bits_per_pixel))
+		return -EINVAL;
+
+	shift = 4 * (regno & 7);
+	mask  = 0xf << shift;
+	/* gray = 0.30*R + 0.58*G + 0.11*B */
+	level = (((red * 77 + green * 151 + blue * 28) >> 20) << shift) & mask;
+	if (cfb->cmap_invert)
+		level = 0xf - level;
+
+	regno = (regno < 8) ? CLPS711X_PALLSW : CLPS711X_PALMSW;
+
+	writel((readl(cfb->base + regno) & ~mask) | level, cfb->base + regno);
+
+	return 0;
+}
+
+static int clps711x_fb_check_var(struct fb_var_screeninfo *var,
+				 struct fb_info *info)
+{
+	u32 val;
+
+	if (var->bits_per_pixel < 1 ||
+	    var->bits_per_pixel > CLPS711X_FB_BPP_MAX)
+		return -EINVAL;
+
+	if (!var->pixclock)
+		return -EINVAL;
+
+	val = DIV_ROUND_UP(var->xres, 16) - 1;
+	if (val < 0x01 || val > 0x3f)
+		return -EINVAL;
+
+	val = DIV_ROUND_UP(var->yres * var->xres * var->bits_per_pixel, 128);
+	val--;
+	if (val < 0x001 || val > 0x1fff)
+		return -EINVAL;
+
+	var->transp.msb_right	= 0;
+	var->transp.offset	= 0;
+	var->transp.length	= 0;
+	var->red.msb_right	= 0;
+	var->red.offset		= 0;
+	var->red.length		= var->bits_per_pixel;
+	var->green		= var->red;
+	var->blue		= var->red;
+	var->grayscale		= var->bits_per_pixel > 1;
+
+	return 0;
+}
+
+static int clps711x_fb_set_par(struct fb_info *info)
+{
+	struct clps711x_fb_info *cfb = info->par;
+	resource_size_t size;
+	u32 lcdcon, pps;
+
+	size = (info->var.xres * info->var.yres * info->var.bits_per_pixel) / 8;
+	if (size > cfb->buffsize)
+		return -EINVAL;
+
+	switch (info->var.bits_per_pixel) {
+	case 1:
+		info->fix.visual = FB_VISUAL_MONO01;
+		break;
+	case 2:
+	case 4:
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	info->fix.line_length = info->var.xres * info->var.bits_per_pixel / 8;
+	info->fix.smem_len = size;
+
+	lcdcon = (info->var.xres * info->var.yres *
+		  info->var.bits_per_pixel) / 128 - 1;
+	lcdcon |= ((info->var.xres / 16) - 1) << 13;
+	lcdcon |= (cfb->ac_prescale & 0x1f) << 25;
+
+	pps = clk_get_rate(cfb->clk) / (PICOS2KHZ(info->var.pixclock) * 1000);
+	if (pps)
+		pps--;
+	lcdcon |= (pps & 0x3f) << 19;
+
+	if (info->var.bits_per_pixel == 4)
+		lcdcon |= LCDCON_GSMD;
+	if (info->var.bits_per_pixel >= 2)
+		lcdcon |= LCDCON_GSEN;
+
+	/* LCDCON must only be changed while the LCD is disabled */
+	regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0);
+	writel(lcdcon, cfb->base + CLPS711X_LCDCON);
+	regmap_update_bits(cfb->syscon, SYSCON_OFFSET,
+			   SYSCON1_LCDEN, SYSCON1_LCDEN);
+
+	return 0;
+}
+
+static int clps711x_fb_blank(int blank, struct fb_info *info)
+{
+	/* Return happy */
+	return 0;
+}
+
+static struct fb_ops clps711x_fb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_setcolreg	= clps711x_fb_setcolreg,
+	.fb_check_var	= clps711x_fb_check_var,
+	.fb_set_par	= clps711x_fb_set_par,
+	.fb_blank	= clps711x_fb_blank,
+	.fb_fillrect	= sys_fillrect,
+	.fb_copyarea	= sys_copyarea,
+	.fb_imageblit	= sys_imageblit,
+};
+
+static int clps711x_lcd_check_fb(struct lcd_device *lcddev, struct fb_info *fi)
+{
+	struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev);
+
+	return (!fi || fi->par == cfb) ? 1 : 0;
+}
+
+static int clps711x_lcd_get_power(struct lcd_device *lcddev)
+{
+	struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev);
+
+	if (!IS_ERR_OR_NULL(cfb->lcd_pwr))
+		if (!regulator_is_enabled(cfb->lcd_pwr))
+			return FB_BLANK_NORMAL;
+
+	return FB_BLANK_UNBLANK;
+}
+
+static int clps711x_lcd_set_power(struct lcd_device *lcddev, int blank)
+{
+	struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev);
+
+	if (!IS_ERR_OR_NULL(cfb->lcd_pwr)) {
+		if (blank == FB_BLANK_UNBLANK) {
+			if (!regulator_is_enabled(cfb->lcd_pwr))
+				return regulator_enable(cfb->lcd_pwr);
+		} else {
+			if (regulator_is_enabled(cfb->lcd_pwr))
+				return regulator_disable(cfb->lcd_pwr);
+		}
+	}
+
+	return 0;
+}
+
+static struct lcd_ops clps711x_lcd_ops = {
+	.check_fb	= clps711x_lcd_check_fb,
+	.get_power	= clps711x_lcd_get_power,
+	.set_power	= clps711x_lcd_set_power,
+};
+
+static int clps711x_fb_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *disp, *np = dev->of_node;
+	struct clps711x_fb_info *cfb;
+	struct lcd_device *lcd;
+	struct fb_info *info;
+	struct resource *res;
+	int ret = -ENOENT;
+	u32 val;
+
+	if (fb_get_options(CLPS711X_FB_NAME, NULL))
+		return -ENODEV;
+
+	info = framebuffer_alloc(sizeof(*cfb), dev);
+	if (!info)
+		return -ENOMEM;
+
+	cfb = info->par;
+	platform_set_drvdata(pdev, info);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		goto out_fb_release;
+	cfb->base = devm_ioremap(dev, res->start, resource_size(res));
+	if (!cfb->base) {
+		ret = -ENOMEM;
+		goto out_fb_release;
+	}
+
+	info->fix.mmio_start = res->start;
+	info->fix.mmio_len = resource_size(res);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	info->screen_base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(info->screen_base)) {
+		ret = PTR_ERR(info->screen_base);
+		goto out_fb_release;
+	}
+
+	/* Physical address should be aligned to 256 MiB */
+	if (res->start & 0x0fffffff) {
+		ret = -EINVAL;
+		goto out_fb_release;
+	}
+
+	info->apertures = alloc_apertures(1);
+	if (!info->apertures) {
+		ret = -ENOMEM;
+		goto out_fb_release;
+	}
+
+	cfb->buffsize = resource_size(res);
+	info->fix.smem_start = res->start;
+	info->apertures->ranges[0].base = info->fix.smem_start;
+	info->apertures->ranges[0].size = cfb->buffsize;
+
+	cfb->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(cfb->clk)) {
+		ret = PTR_ERR(cfb->clk);
+		goto out_fb_release;
+	}
+
+	cfb->syscon =
+		syscon_regmap_lookup_by_compatible("cirrus,clps711x-syscon1");
+	if (IS_ERR(cfb->syscon)) {
+		ret = PTR_ERR(cfb->syscon);
+		goto out_fb_release;
+	}
+
+	disp = of_parse_phandle(np, "display", 0);
+	if (!disp) {
+		dev_err(&pdev->dev, "No display defined\n");
+		ret = -ENODATA;
+		goto out_fb_release;
+	}
+
+	ret = of_get_fb_videomode(disp, &cfb->mode, OF_USE_NATIVE_MODE);
+	if (ret)
+		goto out_fb_release;
+
+	of_property_read_u32(disp, "ac-prescale", &cfb->ac_prescale);
+	cfb->cmap_invert = of_property_read_bool(disp, "cmap-invert");
+
+	ret = of_property_read_u32(disp, "bits-per-pixel",
+				   &info->var.bits_per_pixel);
+	if (ret)
+		goto out_fb_release;
+
+	/* Force disable LCD on any mismatch */
+	if (info->fix.smem_start != (readb(cfb->base + CLPS711X_FBADDR) << 28))
+		regmap_update_bits(cfb->syscon, SYSCON_OFFSET,
+				   SYSCON1_LCDEN, 0);
+
+	ret = regmap_read(cfb->syscon, SYSCON_OFFSET, &val);
+	if (ret)
+		goto out_fb_release;
+
+	if (!(val & SYSCON1_LCDEN)) {
+		/* Setup start FB address */
+		writeb(info->fix.smem_start >> 28, cfb->base + CLPS711X_FBADDR);
+		/* Clean FB memory */
+		memset_io(info->screen_base, 0, cfb->buffsize);
+	}
+
+	cfb->lcd_pwr = devm_regulator_get(dev, "lcd");
+	if (PTR_ERR(cfb->lcd_pwr) == -EPROBE_DEFER) {
+		ret = -EPROBE_DEFER;
+		goto out_fb_release;
+	}
+
+	info->fbops = &clps711x_fb_ops;
+	info->flags = FBINFO_DEFAULT;
+	info->var.activate = FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
+	info->var.height = -1;
+	info->var.width = -1;
+	info->var.vmode = FB_VMODE_NONINTERLACED;
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.accel = FB_ACCEL_NONE;
+	strlcpy(info->fix.id, CLPS711X_FB_NAME, sizeof(info->fix.id));
+	fb_videomode_to_var(&info->var, &cfb->mode);
+
+	ret = fb_alloc_cmap(&info->cmap, BIT(CLPS711X_FB_BPP_MAX), 0);
+	if (ret)
+		goto out_fb_release;
+
+	ret = fb_set_var(info, &info->var);
+	if (ret)
+		goto out_fb_dealloc_cmap;
+
+	ret = register_framebuffer(info);
+	if (ret)
+		goto out_fb_dealloc_cmap;
+
+	lcd = devm_lcd_device_register(dev, "clps711x-lcd", dev, cfb,
+				       &clps711x_lcd_ops);
+	if (!IS_ERR(lcd))
+		return 0;
+	
+	ret = PTR_ERR(lcd);
+	unregister_framebuffer(info);
+
+out_fb_dealloc_cmap:
+	regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0);
+	fb_dealloc_cmap(&info->cmap);
+
+out_fb_release:
+	framebuffer_release(info);
+
+	return ret;
+}
+
+static int clps711x_fb_remove(struct platform_device *pdev)
+{
+	struct fb_info *info = platform_get_drvdata(pdev);
+	struct clps711x_fb_info *cfb = info->par;
+
+	regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0);
+
+	unregister_framebuffer(info);
+	fb_dealloc_cmap(&info->cmap);
+	framebuffer_release(info);
+
+	return 0;
+}
+
+static const struct of_device_id clps711x_fb_dt_ids[] = {
+	{ .compatible = "cirrus,clps711x-fb", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, clps711x_fb_dt_ids);
+
+static struct platform_driver clps711x_fb_driver = {
+	.driver	= {
+		.name		= CLPS711X_FB_NAME,
+		.owner		= THIS_MODULE,
+		.of_match_table	= clps711x_fb_dt_ids,
+	},
+	.probe	= clps711x_fb_probe,
+	.remove	= clps711x_fb_remove,
+};
+module_platform_driver(clps711x_fb_driver);
+
+MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
+MODULE_DESCRIPTION("Cirrus Logic CLPS711X FB driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c
index a8484f768d04..788f6b37fce7 100644
--- a/drivers/video/fbdev/da8xx-fb.c
+++ b/drivers/video/fbdev/da8xx-fb.c
@@ -1447,18 +1447,15 @@ static int fb_probe(struct platform_device *device)
 		da8xx_fb_fix.line_length - 1;
 
 	/* allocate palette buffer */
-	par->v_palette_base = dma_alloc_coherent(NULL,
-					       PALETTE_SIZE,
-					       (resource_size_t *)
-					       &par->p_palette_base,
-					       GFP_KERNEL | GFP_DMA);
+	par->v_palette_base = dma_zalloc_coherent(NULL, PALETTE_SIZE,
+						  (resource_size_t *)&par->p_palette_base,
+						  GFP_KERNEL | GFP_DMA);
 	if (!par->v_palette_base) {
 		dev_err(&device->dev,
 			"GLCD: kmalloc for palette buffer failed\n");
 		ret = -EINVAL;
 		goto err_release_fb_mem;
 	}
-	memset(par->v_palette_base, 0, PALETTE_SIZE);
 
 	par->irq = platform_get_irq(device, 0);
 	if (par->irq < 0) {
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index e23392ec5af3..569e7562fa3d 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -224,6 +224,11 @@ struct hvfb_par {
 	u32 pseudo_palette[16];
 	u8 init_buf[MAX_VMBUS_PKT_SIZE];
 	u8 recv_buf[MAX_VMBUS_PKT_SIZE];
+
+	/* If true, the VSC notifies the VSP on every framebuffer change */
+	bool synchronous_fb;
+
+	struct notifier_block hvfb_panic_nb;
 };
 
 static uint screen_width = HVFB_WIDTH;
@@ -532,6 +537,19 @@ static void hvfb_update_work(struct work_struct *w)
 		schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY);
 }
 
+static int hvfb_on_panic(struct notifier_block *nb,
+			 unsigned long e, void *p)
+{
+	struct hvfb_par *par;
+	struct fb_info *info;
+
+	par = container_of(nb, struct hvfb_par, hvfb_panic_nb);
+	par->synchronous_fb = true;
+	info = par->info;
+	synthvid_update(info);
+
+	return NOTIFY_DONE;
+}
 
 /* Framebuffer operation handlers */
 
@@ -582,14 +600,44 @@ static int hvfb_blank(int blank, struct fb_info *info)
 	return 1;	/* get fb_blank to set the colormap to all black */
 }
 
+static void hvfb_cfb_fillrect(struct fb_info *p,
+			      const struct fb_fillrect *rect)
+{
+	struct hvfb_par *par = p->par;
+
+	cfb_fillrect(p, rect);
+	if (par->synchronous_fb)
+		synthvid_update(p);
+}
+
+static void hvfb_cfb_copyarea(struct fb_info *p,
+			      const struct fb_copyarea *area)
+{
+	struct hvfb_par *par = p->par;
+
+	cfb_copyarea(p, area);
+	if (par->synchronous_fb)
+		synthvid_update(p);
+}
+
+static void hvfb_cfb_imageblit(struct fb_info *p,
+			       const struct fb_image *image)
+{
+	struct hvfb_par *par = p->par;
+
+	cfb_imageblit(p, image);
+	if (par->synchronous_fb)
+		synthvid_update(p);
+}
+
 static struct fb_ops hvfb_ops = {
 	.owner = THIS_MODULE,
 	.fb_check_var = hvfb_check_var,
 	.fb_set_par = hvfb_set_par,
 	.fb_setcolreg = hvfb_setcolreg,
-	.fb_fillrect = cfb_fillrect,
-	.fb_copyarea = cfb_copyarea,
-	.fb_imageblit = cfb_imageblit,
+	.fb_fillrect = hvfb_cfb_fillrect,
+	.fb_copyarea = hvfb_cfb_copyarea,
+	.fb_imageblit = hvfb_cfb_imageblit,
 	.fb_blank = hvfb_blank,
 };
 
@@ -801,6 +849,11 @@ static int hvfb_probe(struct hv_device *hdev,
 
 	par->fb_ready = true;
 
+	par->synchronous_fb = false;
+	par->hvfb_panic_nb.notifier_call = hvfb_on_panic;
+	atomic_notifier_chain_register(&panic_notifier_list,
+				       &par->hvfb_panic_nb);
+
 	return 0;
 
 error:
@@ -820,6 +873,9 @@ static int hvfb_remove(struct hv_device *hdev)
 	struct fb_info *info = hv_get_drvdata(hdev);
 	struct hvfb_par *par = info->par;
 
+	atomic_notifier_chain_unregister(&panic_notifier_list,
+					 &par->hvfb_panic_nb);
+
 	par->update = false;
 	par->fb_ready = false;
 
diff --git a/drivers/video/fbdev/mbx/mbxfb.c b/drivers/video/fbdev/mbx/mbxfb.c
index 2bd52ed8832c..698df9543e30 100644
--- a/drivers/video/fbdev/mbx/mbxfb.c
+++ b/drivers/video/fbdev/mbx/mbxfb.c
@@ -628,14 +628,14 @@ static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd,
 		case MBXFB_IOCS_PLANEORDER:
 			if (copy_from_user(&porder, (void __user*)arg,
 					sizeof(struct mbxfb_planeorder)))
-			return -EFAULT;
+				return -EFAULT;
 
 			return mbxfb_ioctl_planeorder(&porder);
 
 		case MBXFB_IOCS_ALPHA:
 			if (copy_from_user(&alpha, (void __user*)arg,
 					sizeof(struct mbxfb_alphaCtl)))
-			return -EFAULT;
+				return -EFAULT;
 
 			return mbxfb_ioctl_alphactl(&alpha);
 
diff --git a/drivers/video/fbdev/msm/mddi_client_dummy.c b/drivers/video/fbdev/msm/mddi_client_dummy.c
index f1b0dfcc9717..cdb8f69a5d88 100644
--- a/drivers/video/fbdev/msm/mddi_client_dummy.c
+++ b/drivers/video/fbdev/msm/mddi_client_dummy.c
@@ -15,6 +15,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -51,8 +52,7 @@ static int mddi_dummy_probe(struct platform_device *pdev)
 {
 	struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
 	struct panel_info *panel =
-		kzalloc(sizeof(struct panel_info), GFP_KERNEL);
-	int ret;
+		devm_kzalloc(&pdev->dev, sizeof(struct panel_info), GFP_KERNEL);
 	if (!panel)
 		return -ENOMEM;
 	platform_set_drvdata(pdev, panel);
@@ -67,24 +67,11 @@ static int mddi_dummy_probe(struct platform_device *pdev)
 				      client_data->fb_resource, 1);
 	panel->panel_data.fb_data = client_data->private_client_data;
 	panel->pdev.dev.platform_data = &panel->panel_data;
-	ret = platform_device_register(&panel->pdev);
-	if (ret) {
-		kfree(panel);
-		return ret;
-	}
-	return 0;
-}
-
-static int mddi_dummy_remove(struct platform_device *pdev)
-{
-	struct panel_info *panel = platform_get_drvdata(pdev);
-	kfree(panel);
-	return 0;
+	return platform_device_register(&panel->pdev);
 }
 
 static struct platform_driver mddi_client_dummy = {
 	.probe = mddi_dummy_probe,
-	.remove = mddi_dummy_remove,
 	.driver = { .name = "mddi_c_dummy" },
 };
 
diff --git a/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
index 4420ccb69aa9..131c6e260898 100644
--- a/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
@@ -262,6 +262,23 @@ static int hdmic_audio_config(struct omap_dss_device *dssdev,
 	return 0;
 }
 
+static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode)
+{
+	struct panel_drv_data *ddata = to_panel_data(dssdev);
+	struct omap_dss_device *in = ddata->in;
+
+	return in->ops.hdmi->set_hdmi_mode(in, hdmi_mode);
+}
+
+static int hdmic_set_infoframe(struct omap_dss_device *dssdev,
+		const struct hdmi_avi_infoframe *avi)
+{
+	struct panel_drv_data *ddata = to_panel_data(dssdev);
+	struct omap_dss_device *in = ddata->in;
+
+	return in->ops.hdmi->set_infoframe(in, avi);
+}
+
 static struct omap_dss_driver hdmic_driver = {
 	.connect		= hdmic_connect,
 	.disconnect		= hdmic_disconnect,
@@ -277,6 +294,8 @@ static struct omap_dss_driver hdmic_driver = {
 
 	.read_edid		= hdmic_read_edid,
 	.detect			= hdmic_detect,
+	.set_hdmi_mode		= hdmic_set_hdmi_mode,
+	.set_hdmi_infoframe	= hdmic_set_infoframe,
 
 	.audio_enable		= hdmic_audio_enable,
 	.audio_disable		= hdmic_audio_disable,
diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
index 7e33686171e3..c891d8f84cb2 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
@@ -242,6 +242,24 @@ static int tpd_audio_config(struct omap_dss_device *dssdev,
 	return in->ops.hdmi->audio_config(in, audio);
 }
 
+static int tpd_set_infoframe(struct omap_dss_device *dssdev,
+		const struct hdmi_avi_infoframe *avi)
+{
+	struct panel_drv_data *ddata = to_panel_data(dssdev);
+	struct omap_dss_device *in = ddata->in;
+
+	return in->ops.hdmi->set_infoframe(in, avi);
+}
+
+static int tpd_set_hdmi_mode(struct omap_dss_device *dssdev,
+		bool hdmi_mode)
+{
+	struct panel_drv_data *ddata = to_panel_data(dssdev);
+	struct omap_dss_device *in = ddata->in;
+
+	return in->ops.hdmi->set_hdmi_mode(in, hdmi_mode);
+}
+
 static const struct omapdss_hdmi_ops tpd_hdmi_ops = {
 	.connect		= tpd_connect,
 	.disconnect		= tpd_disconnect,
@@ -255,6 +273,8 @@ static const struct omapdss_hdmi_ops tpd_hdmi_ops = {
 
 	.read_edid		= tpd_read_edid,
 	.detect			= tpd_detect,
+	.set_infoframe		= tpd_set_infoframe,
+	.set_hdmi_mode		= tpd_set_hdmi_mode,
 
 	.audio_enable		= tpd_audio_enable,
 	.audio_disable		= tpd_audio_disable,
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
index c7ba4d8b928a..617f8d2f5127 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
@@ -817,6 +817,10 @@ static int acx565akm_probe(struct spi_device *spi)
 
 	bldev = backlight_device_register("acx565akm", &ddata->spi->dev,
 			ddata, &acx565akm_bl_ops, &props);
+	if (IS_ERR(bldev)) {
+		r = PTR_ERR(bldev);
+		goto err_reg_bl;
+	}
 	ddata->bl_dev = bldev;
 	if (ddata->has_cabc) {
 		r = sysfs_create_group(&bldev->dev.kobj, &bldev_attr_group);
@@ -862,6 +866,7 @@ err_reg:
 	sysfs_remove_group(&bldev->dev.kobj, &bldev_attr_group);
 err_sysfs:
 	backlight_device_unregister(bldev);
+err_reg_bl:
 err_detect:
 err_gpio:
 	omap_dss_put_device(ddata->in);
diff --git a/drivers/video/fbdev/omap2/dss/Kconfig b/drivers/video/fbdev/omap2/dss/Kconfig
index 285bcd103dce..3d5eb6c36c22 100644
--- a/drivers/video/fbdev/omap2/dss/Kconfig
+++ b/drivers/video/fbdev/omap2/dss/Kconfig
@@ -5,6 +5,7 @@ menuconfig OMAP2_DSS
         tristate "OMAP2+ Display Subsystem support"
 	select VIDEOMODE_HELPERS
 	select OMAP2_DSS_INIT
+	select HDMI
         help
 	  OMAP2+ Display Subsystem support.
 
diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index 7aa33b0f4a1f..be053aa80880 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -2879,19 +2879,24 @@ static bool _dispc_mgr_pclk_ok(enum omap_channel channel,
 bool dispc_mgr_timings_ok(enum omap_channel channel,
 		const struct omap_video_timings *timings)
 {
-	bool timings_ok;
-
-	timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
+	if (!_dispc_mgr_size_ok(timings->x_res, timings->y_res))
+		return false;
 
-	timings_ok &= _dispc_mgr_pclk_ok(channel, timings->pixelclock);
+	if (!_dispc_mgr_pclk_ok(channel, timings->pixelclock))
+		return false;
 
 	if (dss_mgr_is_lcd(channel)) {
-		timings_ok &= _dispc_lcd_timings_ok(timings->hsw, timings->hfp,
+		/* TODO: OMAP4+ supports interlace for LCD outputs */
+		if (timings->interlace)
+			return false;
+
+		if (!_dispc_lcd_timings_ok(timings->hsw, timings->hfp,
 				timings->hbp, timings->vsw, timings->vfp,
-				timings->vbp);
+				timings->vbp))
+			return false;
 	}
 
-	return timings_ok;
+	return true;
 }
 
 static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
@@ -3257,13 +3262,10 @@ static void dispc_dump_regs(struct seq_file *s)
 		if (i == OMAP_DSS_CHANNEL_DIGIT)
 			continue;
 
-		DUMPREG(i, DISPC_DEFAULT_COLOR);
-		DUMPREG(i, DISPC_TRANS_COLOR);
 		DUMPREG(i, DISPC_TIMING_H);
 		DUMPREG(i, DISPC_TIMING_V);
 		DUMPREG(i, DISPC_POL_FREQ);
 		DUMPREG(i, DISPC_DIVISORo);
-		DUMPREG(i, DISPC_SIZE_MGR);
 
 		DUMPREG(i, DISPC_DATA_CYCLE1);
 		DUMPREG(i, DISPC_DATA_CYCLE2);
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index 4755a34a5422..56b92444c54f 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -5658,18 +5658,11 @@ err_runtime_get:
 	return r;
 }
 
-static int dsi_unregister_child(struct device *dev, void *data)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	platform_device_unregister(pdev);
-	return 0;
-}
-
 static int __exit omap_dsihw_remove(struct platform_device *dsidev)
 {
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
-	device_for_each_child(&dsidev->dev, NULL, dsi_unregister_child);
+	of_platform_depopulate(&dsidev->dev);
 
 	WARN_ON(dsi->scp_clk_refcount > 0);
 
diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h
index fbee07816337..262771b9b76b 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi.h
@@ -22,6 +22,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/hdmi.h>
 #include <video/omapdss.h>
 
 #include "dss.h"
@@ -142,7 +143,7 @@ enum hdmi_audio_samples_perword {
 	HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1
 };
 
-enum hdmi_audio_sample_size {
+enum hdmi_audio_sample_size_omap {
 	HDMI_AUDIO_SAMPLE_16BITS = 0,
 	HDMI_AUDIO_SAMPLE_24BITS = 1
 };
@@ -178,59 +179,6 @@ enum hdmi_audio_mclk_mode {
 	HDMI_AUDIO_MCLK_192FS = 7
 };
 
-/* INFOFRAME_AVI_ and INFOFRAME_AUDIO_ definitions */
-enum hdmi_core_infoframe {
-	HDMI_INFOFRAME_AVI_DB1Y_RGB = 0,
-	HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1,
-	HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2,
-	HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0,
-	HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON =  1,
-	HDMI_INFOFRAME_AVI_DB1B_NO = 0,
-	HDMI_INFOFRAME_AVI_DB1B_VERT = 1,
-	HDMI_INFOFRAME_AVI_DB1B_HORI = 2,
-	HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3,
-	HDMI_INFOFRAME_AVI_DB1S_0 = 0,
-	HDMI_INFOFRAME_AVI_DB1S_1 = 1,
-	HDMI_INFOFRAME_AVI_DB1S_2 = 2,
-	HDMI_INFOFRAME_AVI_DB2C_NO = 0,
-	HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1,
-	HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2,
-	HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3,
-	HDMI_INFOFRAME_AVI_DB2M_NO = 0,
-	HDMI_INFOFRAME_AVI_DB2M_43 = 1,
-	HDMI_INFOFRAME_AVI_DB2M_169 = 2,
-	HDMI_INFOFRAME_AVI_DB2R_SAME = 8,
-	HDMI_INFOFRAME_AVI_DB2R_43 = 9,
-	HDMI_INFOFRAME_AVI_DB2R_169 = 10,
-	HDMI_INFOFRAME_AVI_DB2R_149 = 11,
-	HDMI_INFOFRAME_AVI_DB3ITC_NO = 0,
-	HDMI_INFOFRAME_AVI_DB3ITC_YES = 1,
-	HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0,
-	HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1,
-	HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0,
-	HDMI_INFOFRAME_AVI_DB3Q_LR = 1,
-	HDMI_INFOFRAME_AVI_DB3Q_FR = 2,
-	HDMI_INFOFRAME_AVI_DB3SC_NO = 0,
-	HDMI_INFOFRAME_AVI_DB3SC_HORI = 1,
-	HDMI_INFOFRAME_AVI_DB3SC_VERT = 2,
-	HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3,
-	HDMI_INFOFRAME_AVI_DB5PR_NO = 0,
-	HDMI_INFOFRAME_AVI_DB5PR_2 = 1,
-	HDMI_INFOFRAME_AVI_DB5PR_3 = 2,
-	HDMI_INFOFRAME_AVI_DB5PR_4 = 3,
-	HDMI_INFOFRAME_AVI_DB5PR_5 = 4,
-	HDMI_INFOFRAME_AVI_DB5PR_6 = 5,
-	HDMI_INFOFRAME_AVI_DB5PR_7 = 6,
-	HDMI_INFOFRAME_AVI_DB5PR_8 = 7,
-	HDMI_INFOFRAME_AVI_DB5PR_9 = 8,
-	HDMI_INFOFRAME_AVI_DB5PR_10 = 9,
-};
-
-struct hdmi_cm {
-	int	code;
-	int	mode;
-};
-
 struct hdmi_video_format {
 	enum hdmi_packing_mode	packing_mode;
 	u32			y_res;	/* Line per panel */
@@ -239,7 +187,8 @@ struct hdmi_video_format {
 
 struct hdmi_config {
 	struct omap_video_timings timings;
-	struct hdmi_cm cm;
+	struct hdmi_avi_infoframe infoframe;
+	enum hdmi_core_hdmi_dvi hdmi_dvi_mode;
 };
 
 /* HDMI PLL structure */
@@ -260,7 +209,7 @@ struct hdmi_audio_format {
 	enum hdmi_audio_justify			justification;
 	enum hdmi_audio_sample_order		sample_order;
 	enum hdmi_audio_samples_perword		samples_per_word;
-	enum hdmi_audio_sample_size		sample_size;
+	enum hdmi_audio_sample_size_omap	sample_size;
 	enum hdmi_audio_blk_strt_end_sig	en_sig_blk_strt_end;
 };
 
@@ -298,47 +247,6 @@ struct hdmi_core_audio_config {
 	bool					en_spdif;
 };
 
-/*
- * Refer to section 8.2 in HDMI 1.3 specification for
- * details about infoframe databytes
- */
-struct hdmi_core_infoframe_avi {
-	/* Y0, Y1 rgb,yCbCr */
-	u8	db1_format;
-	/* A0  Active information Present */
-	u8	db1_active_info;
-	/* B0, B1 Bar info data valid */
-	u8	db1_bar_info_dv;
-	/* S0, S1 scan information */
-	u8	db1_scan_info;
-	/* C0, C1 colorimetry */
-	u8	db2_colorimetry;
-	/* M0, M1 Aspect ratio (4:3, 16:9) */
-	u8	db2_aspect_ratio;
-	/* R0...R3 Active format aspect ratio */
-	u8	db2_active_fmt_ar;
-	/* ITC IT content. */
-	u8	db3_itc;
-	/* EC0, EC1, EC2 Extended colorimetry */
-	u8	db3_ec;
-	/* Q1, Q0 Quantization range */
-	u8	db3_q_range;
-	/* SC1, SC0 Non-uniform picture scaling */
-	u8	db3_nup_scaling;
-	/* VIC0..6 Video format identification */
-	u8	db4_videocode;
-	/* PR0..PR3 Pixel repetition factor */
-	u8	db5_pixel_repeat;
-	/* Line number end of top bar */
-	u16	db6_7_line_eoftop;
-	/* Line number start of bottom bar */
-	u16	db8_9_line_sofbottom;
-	/* Pixel number end of left bar */
-	u16	db10_11_pixel_eofleft;
-	/* Pixel number start of right bar */
-	u16	db12_13_pixel_sofright;
-};
-
 struct hdmi_wp_data {
 	void __iomem *base;
 };
@@ -358,8 +266,6 @@ struct hdmi_phy_data {
 
 struct hdmi_core_data {
 	void __iomem *base;
-
-	struct hdmi_core_infoframe_avi avi_cfg;
 };
 
 static inline void hdmi_write_reg(void __iomem *base_addr, const u32 idx,
@@ -425,9 +331,6 @@ int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy);
 int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes);
 
 /* HDMI common funcs */
-const struct hdmi_config *hdmi_default_timing(void);
-const struct hdmi_config *hdmi_get_timings(int mode, int code);
-struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing);
 int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep,
 	struct hdmi_phy_data *phy);
 
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c
index 626aad2bef46..6a8550cf43e5 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
@@ -281,29 +281,11 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
 static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	struct hdmi_cm cm;
-	const struct hdmi_config *t;
-
 	mutex_lock(&hdmi.lock);
 
-	cm = hdmi_get_code(timings);
-	hdmi.cfg.cm = cm;
-
-	t = hdmi_get_timings(cm.mode, cm.code);
-	if (t != NULL) {
-		hdmi.cfg = *t;
-
-		dispc_set_tv_pclk(t->timings.pixelclock);
-	} else {
-		hdmi.cfg.timings = *timings;
-		hdmi.cfg.cm.code = 0;
-		hdmi.cfg.cm.mode = HDMI_DVI;
-
-		dispc_set_tv_pclk(timings->pixelclock);
-	}
+	hdmi.cfg.timings = *timings;
 
-	DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ?
-			"DVI" : "HDMI", hdmi.cfg.cm.code);
+	dispc_set_tv_pclk(timings->pixelclock);
 
 	mutex_unlock(&hdmi.lock);
 }
@@ -311,14 +293,7 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
 static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	const struct hdmi_config *cfg;
-	struct hdmi_cm cm = hdmi.cfg.cm;
-
-	cfg = hdmi_get_timings(cm.mode, cm.code);
-	if (cfg == NULL)
-		cfg = hdmi_default_timing();
-
-	memcpy(timings, &cfg->timings, sizeof(cfg->timings));
+	*timings = hdmi.cfg.timings;
 }
 
 static void hdmi_dump_regs(struct seq_file *s)
@@ -516,7 +491,7 @@ static int hdmi_audio_enable(struct omap_dss_device *dssdev)
 
 	mutex_lock(&hdmi.lock);
 
-	if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) {
+	if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
 		r = -EPERM;
 		goto err;
 	}
@@ -554,7 +529,7 @@ static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
 
 	mutex_lock(&hdmi.lock);
 
-	r = hdmi_mode_has_audio(hdmi.cfg.cm.mode);
+	r = hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode);
 
 	mutex_unlock(&hdmi.lock);
 	return r;
@@ -568,7 +543,7 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
 
 	mutex_lock(&hdmi.lock);
 
-	if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) {
+	if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
 		r = -EPERM;
 		goto err;
 	}
@@ -615,6 +590,20 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
 }
 #endif
 
+static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
+		const struct hdmi_avi_infoframe *avi)
+{
+	hdmi.cfg.infoframe = *avi;
+	return 0;
+}
+
+static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
+		bool hdmi_mode)
+{
+	hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
+	return 0;
+}
+
 static const struct omapdss_hdmi_ops hdmi_ops = {
 	.connect		= hdmi_connect,
 	.disconnect		= hdmi_disconnect,
@@ -627,6 +616,8 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
 	.get_timings		= hdmi_display_get_timings,
 
 	.read_edid		= hdmi_read_edid,
+	.set_infoframe		= hdmi_set_infoframe,
+	.set_hdmi_mode		= hdmi_set_hdmi_mode,
 
 	.audio_enable		= hdmi_audio_enable,
 	.audio_disable		= hdmi_audio_disable,
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.c b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
index 8bde7b7e95ff..4ad39cfce254 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
@@ -197,9 +197,7 @@ int hdmi4_read_edid(struct hdmi_core_data *core, u8 *edid, int len)
 	return l;
 }
 
-static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
-			struct hdmi_core_infoframe_avi *avi_cfg,
-			struct hdmi_core_packet_enable_repeat *repeat_cfg)
+static void hdmi_core_init(struct hdmi_core_video_config *video_cfg)
 {
 	DSSDBG("Enter hdmi_core_init\n");
 
@@ -210,35 +208,6 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
 	video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
 	video_cfg->hdmi_dvi = HDMI_DVI;
 	video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
-
-	/* info frame */
-	avi_cfg->db1_format = 0;
-	avi_cfg->db1_active_info = 0;
-	avi_cfg->db1_bar_info_dv = 0;
-	avi_cfg->db1_scan_info = 0;
-	avi_cfg->db2_colorimetry = 0;
-	avi_cfg->db2_aspect_ratio = 0;
-	avi_cfg->db2_active_fmt_ar = 0;
-	avi_cfg->db3_itc = 0;
-	avi_cfg->db3_ec = 0;
-	avi_cfg->db3_q_range = 0;
-	avi_cfg->db3_nup_scaling = 0;
-	avi_cfg->db4_videocode = 0;
-	avi_cfg->db5_pixel_repeat = 0;
-	avi_cfg->db6_7_line_eoftop = 0;
-	avi_cfg->db8_9_line_sofbottom = 0;
-	avi_cfg->db10_11_pixel_eofleft = 0;
-	avi_cfg->db12_13_pixel_sofright = 0;
-
-	/* packet enable and repeat */
-	repeat_cfg->audio_pkt = 0;
-	repeat_cfg->audio_pkt_repeat = 0;
-	repeat_cfg->avi_infoframe = 0;
-	repeat_cfg->avi_infoframe_repeat = 0;
-	repeat_cfg->gen_cntrl_pkt = 0;
-	repeat_cfg->gen_cntrl_pkt_repeat = 0;
-	repeat_cfg->generic_pkt = 0;
-	repeat_cfg->generic_pkt_repeat = 0;
 }
 
 static void hdmi_core_powerdown_disable(struct hdmi_core_data *core)
@@ -303,80 +272,22 @@ static void hdmi_core_video_config(struct hdmi_core_data *core,
 			HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5);
 }
 
-static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core)
+static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core,
+	struct hdmi_avi_infoframe *frame)
 {
-	u32 val;
-	char sum = 0, checksum = 0;
 	void __iomem *av_base = hdmi_av_base(core);
-	struct hdmi_core_infoframe_avi info_avi = core->avi_cfg;
-
-	sum += 0x82 + 0x002 + 0x00D;
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_TYPE, 0x082);
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_VERS, 0x002);
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_LEN, 0x00D);
-
-	val = (info_avi.db1_format << 5) |
-		(info_avi.db1_active_info << 4) |
-		(info_avi.db1_bar_info_dv << 2) |
-		(info_avi.db1_scan_info);
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(0), val);
-	sum += val;
-
-	val = (info_avi.db2_colorimetry << 6) |
-		(info_avi.db2_aspect_ratio << 4) |
-		(info_avi.db2_active_fmt_ar);
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(1), val);
-	sum += val;
-
-	val = (info_avi.db3_itc << 7) |
-		(info_avi.db3_ec << 4) |
-		(info_avi.db3_q_range << 2) |
-		(info_avi.db3_nup_scaling);
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(2), val);
-	sum += val;
-
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(3),
-					info_avi.db4_videocode);
-	sum += info_avi.db4_videocode;
-
-	val = info_avi.db5_pixel_repeat;
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(4), val);
-	sum += val;
-
-	val = info_avi.db6_7_line_eoftop & 0x00FF;
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(5), val);
-	sum += val;
-
-	val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(6), val);
-	sum += val;
-
-	val = info_avi.db8_9_line_sofbottom & 0x00FF;
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(7), val);
-	sum += val;
-
-	val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(8), val);
-	sum += val;
-
-	val = info_avi.db10_11_pixel_eofleft & 0x00FF;
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(9), val);
-	sum += val;
-
-	val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(10), val);
-	sum += val;
-
-	val = info_avi.db12_13_pixel_sofright & 0x00FF;
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(11), val);
-	sum += val;
-
-	val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(12), val);
-	sum += val;
+	u8 data[HDMI_INFOFRAME_SIZE(AVI)];
+	int i;
 
-	checksum = 0x100 - sum;
-	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_CHSUM, checksum);
+	hdmi_avi_infoframe_pack(frame, data, sizeof(data));
+
+	print_hex_dump_debug("AVI: ", DUMP_PREFIX_NONE, 16, 1, data,
+		HDMI_INFOFRAME_SIZE(AVI), false);
+
+	for (i = 0; i < sizeof(data); ++i) {
+		hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_BASE + i * 4,
+			data[i]);
+	}
 }
 
 static void hdmi_core_av_packet_config(struct hdmi_core_data *core,
@@ -404,11 +315,10 @@ void hdmi4_configure(struct hdmi_core_data *core,
 	struct omap_video_timings video_timing;
 	struct hdmi_video_format video_format;
 	/* HDMI core */
-	struct hdmi_core_infoframe_avi *avi_cfg = &core->avi_cfg;
 	struct hdmi_core_video_config v_core_cfg;
-	struct hdmi_core_packet_enable_repeat repeat_cfg;
+	struct hdmi_core_packet_enable_repeat repeat_cfg = { 0 };
 
-	hdmi_core_init(&v_core_cfg, avi_cfg, &repeat_cfg);
+	hdmi_core_init(&v_core_cfg);
 
 	hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg);
 
@@ -431,44 +341,24 @@ void hdmi4_configure(struct hdmi_core_data *core,
 	hdmi_core_powerdown_disable(core);
 
 	v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
-	v_core_cfg.hdmi_dvi = cfg->cm.mode;
+	v_core_cfg.hdmi_dvi = cfg->hdmi_dvi_mode;
 
 	hdmi_core_video_config(core, &v_core_cfg);
 
 	/* release software reset in the core */
 	hdmi_core_swreset_release(core);
 
-	/*
-	 * configure packet
-	 * info frame video see doc CEA861-D page 65
-	 */
-	avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
-	avi_cfg->db1_active_info =
-			HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
-	avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
-	avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
-	avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
-	avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
-	avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
-	avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
-	avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
-	avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
-	avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
-	avi_cfg->db4_videocode = cfg->cm.code;
-	avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
-	avi_cfg->db6_7_line_eoftop = 0;
-	avi_cfg->db8_9_line_sofbottom = 0;
-	avi_cfg->db10_11_pixel_eofleft = 0;
-	avi_cfg->db12_13_pixel_sofright = 0;
-
-	hdmi_core_aux_infoframe_avi_config(core);
+	if (cfg->hdmi_dvi_mode == HDMI_HDMI) {
+		hdmi_core_write_avi_infoframe(core, &cfg->infoframe);
+
+		/* enable/repeat the infoframe */
+		repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
+		repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
+		/* wakeup */
+		repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
+		repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
+	}
 
-	/* enable/repeat the infoframe */
-	repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
-	repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
-	/* wakeup */
-	repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
-	repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
 	hdmi_core_av_packet_config(core, repeat_cfg);
 }
 
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.h b/drivers/video/fbdev/omap2/dss/hdmi4_core.h
index bb646896fa82..827909eb6c50 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4_core.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.h
@@ -145,6 +145,7 @@
 #define HDMI_CORE_AV_DPD			0xF4
 #define HDMI_CORE_AV_PB_CTRL1			0xF8
 #define HDMI_CORE_AV_PB_CTRL2			0xFC
+#define HDMI_CORE_AV_AVI_BASE			0x100
 #define HDMI_CORE_AV_AVI_TYPE			0x100
 #define HDMI_CORE_AV_AVI_VERS			0x104
 #define HDMI_CORE_AV_AVI_LEN			0x108
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c
index c468b9e1f295..32d02ec34d23 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5.c
@@ -299,29 +299,11 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
 static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	struct hdmi_cm cm;
-	const struct hdmi_config *t;
-
 	mutex_lock(&hdmi.lock);
 
-	cm = hdmi_get_code(timings);
-	hdmi.cfg.cm = cm;
-
-	t = hdmi_get_timings(cm.mode, cm.code);
-	if (t != NULL) {
-		hdmi.cfg = *t;
-
-		dispc_set_tv_pclk(t->timings.pixelclock);
-	} else {
-		hdmi.cfg.timings = *timings;
-		hdmi.cfg.cm.code = 0;
-		hdmi.cfg.cm.mode = HDMI_DVI;
-
-		dispc_set_tv_pclk(timings->pixelclock);
-	}
+	hdmi.cfg.timings = *timings;
 
-	DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ?
-			"DVI" : "HDMI", hdmi.cfg.cm.code);
+	dispc_set_tv_pclk(timings->pixelclock);
 
 	mutex_unlock(&hdmi.lock);
 }
@@ -329,14 +311,7 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
 static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	const struct hdmi_config *cfg;
-	struct hdmi_cm cm = hdmi.cfg.cm;
-
-	cfg = hdmi_get_timings(cm.mode, cm.code);
-	if (cfg == NULL)
-		cfg = hdmi_default_timing();
-
-	memcpy(timings, &cfg->timings, sizeof(cfg->timings));
+	*timings = hdmi.cfg.timings;
 }
 
 static void hdmi_dump_regs(struct seq_file *s)
@@ -541,7 +516,7 @@ static int hdmi_audio_enable(struct omap_dss_device *dssdev)
 
 	mutex_lock(&hdmi.lock);
 
-	if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) {
+	if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
 		r = -EPERM;
 		goto err;
 	}
@@ -579,7 +554,7 @@ static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
 
 	mutex_lock(&hdmi.lock);
 
-	r = hdmi_mode_has_audio(hdmi.cfg.cm.mode);
+	r = hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode);
 
 	mutex_unlock(&hdmi.lock);
 	return r;
@@ -593,7 +568,7 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
 
 	mutex_lock(&hdmi.lock);
 
-	if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) {
+	if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
 		r = -EPERM;
 		goto err;
 	}
@@ -640,6 +615,20 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
 }
 #endif
 
+static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
+		const struct hdmi_avi_infoframe *avi)
+{
+	hdmi.cfg.infoframe = *avi;
+	return 0;
+}
+
+static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
+		bool hdmi_mode)
+{
+	hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
+	return 0;
+}
+
 static const struct omapdss_hdmi_ops hdmi_ops = {
 	.connect		= hdmi_connect,
 	.disconnect		= hdmi_disconnect,
@@ -652,6 +641,8 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
 	.get_timings		= hdmi_display_get_timings,
 
 	.read_edid		= hdmi_read_edid,
+	.set_infoframe		= hdmi_set_infoframe,
+	.set_hdmi_mode		= hdmi_set_hdmi_mode,
 
 	.audio_enable		= hdmi_audio_enable,
 	.audio_disable		= hdmi_audio_disable,
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.c b/drivers/video/fbdev/omap2/dss/hdmi5_core.c
index 7528c7a42aa5..83acbf7a8c89 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.c
@@ -290,7 +290,6 @@ void hdmi5_core_dump(struct hdmi_core_data *core, struct seq_file *s)
 }
 
 static void hdmi_core_init(struct hdmi_core_vid_config *video_cfg,
-			struct hdmi_core_infoframe_avi *avi_cfg,
 			struct hdmi_config *cfg)
 {
 	DSSDBG("hdmi_core_init\n");
@@ -312,27 +311,8 @@ static void hdmi_core_init(struct hdmi_core_vid_config *video_cfg,
 	video_cfg->vblank_osc = 0; /* Always 0 - need to confirm */
 	video_cfg->vblank = cfg->timings.vsw +
 				cfg->timings.vfp + cfg->timings.vbp;
-	video_cfg->v_fc_config.cm.mode = cfg->cm.mode;
+	video_cfg->v_fc_config.hdmi_dvi_mode = cfg->hdmi_dvi_mode;
 	video_cfg->v_fc_config.timings.interlace = cfg->timings.interlace;
-
-	/* info frame */
-	avi_cfg->db1_format = 0;
-	avi_cfg->db1_active_info = 0;
-	avi_cfg->db1_bar_info_dv = 0;
-	avi_cfg->db1_scan_info = 0;
-	avi_cfg->db2_colorimetry = 0;
-	avi_cfg->db2_aspect_ratio = 0;
-	avi_cfg->db2_active_fmt_ar = 0;
-	avi_cfg->db3_itc = 0;
-	avi_cfg->db3_ec = 0;
-	avi_cfg->db3_q_range = 0;
-	avi_cfg->db3_nup_scaling = 0;
-	avi_cfg->db4_videocode = 0;
-	avi_cfg->db5_pixel_repeat = 0;
-	avi_cfg->db6_7_line_eoftop = 0;
-	avi_cfg->db8_9_line_sofbottom = 0;
-	avi_cfg->db10_11_pixel_eofleft = 0;
-	avi_cfg->db12_13_pixel_sofright = 0;
 }
 
 /* DSS_HDMI_CORE_VIDEO_CONFIG */
@@ -398,7 +378,7 @@ static void hdmi_core_video_config(struct hdmi_core_data *core,
 
 	/* select DVI mode */
 	REG_FLD_MOD(base, HDMI_CORE_FC_INVIDCONF,
-			cfg->v_fc_config.cm.mode, 3, 3);
+			cfg->v_fc_config.hdmi_dvi_mode, 3, 3);
 }
 
 static void hdmi_core_config_video_packetizer(struct hdmi_core_data *core)
@@ -438,24 +418,60 @@ static void hdmi_core_config_video_sampler(struct hdmi_core_data *core)
 	REG_FLD_MOD(core->base, HDMI_CORE_TX_INVID0, video_mapping, 4, 0);
 }
 
-static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core)
+static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core,
+	struct hdmi_avi_infoframe *frame)
 {
 	void __iomem *base = core->base;
-	struct hdmi_core_infoframe_avi avi = core->avi_cfg;
-
-	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_format, 1, 0);
-	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_active_info, 6, 6);
-	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_bar_info_dv, 3, 2);
-	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_scan_info, 5, 4);
-	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_colorimetry, 7, 6);
-	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_aspect_ratio, 5, 4);
-	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_active_fmt_ar, 3, 0);
-	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_itc, 7, 7);
-	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_ec, 6, 4);
-	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_q_range, 3, 2);
-	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_nup_scaling, 1, 0);
-	REG_FLD_MOD(base, HDMI_CORE_FC_AVIVID, avi.db4_videocode, 6, 0);
-	REG_FLD_MOD(base, HDMI_CORE_FC_PRCONF, avi.db5_pixel_repeat, 3, 0);
+	u8 data[HDMI_INFOFRAME_SIZE(AVI)];
+	u8 *ptr;
+	unsigned y, a, b, s;
+	unsigned c, m, r;
+	unsigned itc, ec, q, sc;
+	unsigned vic;
+	unsigned yq, cn, pr;
+
+	hdmi_avi_infoframe_pack(frame, data, sizeof(data));
+
+	print_hex_dump_debug("AVI: ", DUMP_PREFIX_NONE, 16, 1, data,
+		HDMI_INFOFRAME_SIZE(AVI), false);
+
+	ptr = data + HDMI_INFOFRAME_HEADER_SIZE;
+
+	y = (ptr[0] >> 5) & 0x3;
+	a = (ptr[0] >> 4) & 0x1;
+	b = (ptr[0] >> 2) & 0x3;
+	s = (ptr[0] >> 0) & 0x3;
+
+	c = (ptr[1] >> 6) & 0x3;
+	m = (ptr[1] >> 4) & 0x3;
+	r = (ptr[1] >> 0) & 0x3;
+
+	itc = (ptr[2] >> 7) & 0x1;
+	ec = (ptr[2] >> 4) & 0x7;
+	q = (ptr[2] >> 2) & 0x3;
+	sc = (ptr[2] >> 0) & 0x3;
+
+	vic = ptr[3];
+
+	yq = (ptr[4] >> 6) & 0x3;
+	cn = (ptr[4] >> 4) & 0x3;
+	pr = (ptr[4] >> 0) & 0xf;
+
+	hdmi_write_reg(base, HDMI_CORE_FC_AVICONF0,
+		(a << 6) | (s << 4) | (b << 2) | (y << 0));
+
+	hdmi_write_reg(base, HDMI_CORE_FC_AVICONF1,
+		(c << 6) | (m << 4) | (r << 0));
+
+	hdmi_write_reg(base, HDMI_CORE_FC_AVICONF2,
+		(itc << 7) | (ec << 4) | (q << 2) | (sc << 0));
+
+	hdmi_write_reg(base, HDMI_CORE_FC_AVIVID, vic);
+
+	hdmi_write_reg(base, HDMI_CORE_FC_AVICONF3,
+		(yq << 2) | (cn << 0));
+
+	REG_FLD_MOD(base, HDMI_CORE_FC_PRCONF, pr, 3, 0);
 }
 
 static void hdmi_core_csc_config(struct hdmi_core_data *core,
@@ -497,10 +513,8 @@ static void hdmi_core_configure_range(struct hdmi_core_data *core)
 
 	/* support limited range with 24 bit color depth for now */
 	csc_coeff = csc_table_deepcolor[0];
-	core->avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_LR;
 
 	hdmi_core_csc_config(core, csc_coeff);
-	hdmi_core_aux_infoframe_avi_config(core);
 }
 
 static void hdmi_core_enable_video_path(struct hdmi_core_data *core)
@@ -591,11 +605,10 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
 	struct omap_video_timings video_timing;
 	struct hdmi_video_format video_format;
 	struct hdmi_core_vid_config v_core_cfg;
-	struct hdmi_core_infoframe_avi *avi_cfg = &core->avi_cfg;
 
 	hdmi_core_mask_interrupts(core);
 
-	hdmi_core_init(&v_core_cfg, avi_cfg, cfg);
+	hdmi_core_init(&v_core_cfg, cfg);
 
 	hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg);
 
@@ -608,7 +621,9 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
 
 	hdmi_wp_video_config_interface(wp, &video_timing);
 
+	/* support limited range with 24 bit color depth for now */
 	hdmi_core_configure_range(core);
+	cfg->infoframe.quantization_range = HDMI_QUANTIZATION_RANGE_LIMITED;
 
 	/*
 	 * configure core video part, set software reset in the core
@@ -621,29 +636,8 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
 	hdmi_core_config_csc(core);
 	hdmi_core_config_video_sampler(core);
 
-	/*
-	 * configure packet info frame video see doc CEA861-D page 65
-	 */
-	avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
-	avi_cfg->db1_active_info =
-			HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
-	avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
-	avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
-	avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
-	avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
-	avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
-	avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
-	avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
-	avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
-	avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
-	avi_cfg->db4_videocode = cfg->cm.code;
-	avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
-	avi_cfg->db6_7_line_eoftop = 0;
-	avi_cfg->db8_9_line_sofbottom = 0;
-	avi_cfg->db10_11_pixel_eofleft = 0;
-	avi_cfg->db12_13_pixel_sofright = 0;
-
-	hdmi_core_aux_infoframe_avi_config(core);
+	if (cfg->hdmi_dvi_mode == HDMI_HDMI)
+		hdmi_core_write_avi_infoframe(core, &cfg->infoframe);
 
 	hdmi_core_enable_video_path(core);
 
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_common.c b/drivers/video/fbdev/omap2/dss/hdmi_common.c
index 9a2c39cf297f..7d5f1039de9f 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_common.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_common.c
@@ -1,18 +1,4 @@
 
-/*
- * Logic for the below structure :
- * user enters the CEA or VESA timings by specifying the HDMI/DVI code.
- * There is a correspondence between CEA/VESA timing and code, please
- * refer to section 6.3 in HDMI 1.3 specification for timing code.
- *
- * In the below structure, cea_vesa_timings corresponds to all OMAP4
- * supported CEA and VESA timing values.code_cea corresponds to the CEA
- * code, It is used to get the timing from cea_vesa_timing array.Similarly
- * with code_vesa. Code_index is used for back mapping, that is once EDID
- * is read from the TV, EDID is parsed to find the timing values and then
- * map it to corresponding CEA or VESA index.
- */
-
 #define DSS_SUBSYS_NAME "HDMI"
 
 #include <linux/kernel.h>
@@ -22,308 +8,6 @@
 
 #include "hdmi.h"
 
-static const struct hdmi_config cea_timings[] = {
-	{
-		{ 640, 480, 25200000, 96, 16, 48, 2, 10, 33,
-			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
-			false, },
-		{ 1, HDMI_HDMI },
-	},
-	{
-		{ 720, 480, 27027000, 62, 16, 60, 6, 9, 30,
-			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
-			false, },
-		{ 2, HDMI_HDMI },
-	},
-	{
-		{ 1280, 720, 74250000, 40, 110, 220, 5, 5, 20,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 4, HDMI_HDMI },
-	},
-	{
-		{ 1920, 540, 74250000, 44, 88, 148, 5, 2, 15,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			true, },
-		{ 5, HDMI_HDMI },
-	},
-	{
-		{ 1440, 240, 27027000, 124, 38, 114, 3, 4, 15,
-			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
-			true, },
-		{ 6, HDMI_HDMI },
-	},
-	{
-		{ 1920, 1080, 148500000, 44, 88, 148, 5, 4, 36,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 16, HDMI_HDMI },
-	},
-	{
-		{ 720, 576, 27000000, 64, 12, 68, 5, 5, 39,
-			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
-			false, },
-		{ 17, HDMI_HDMI },
-	},
-	{
-		{ 1280, 720, 74250000, 40, 440, 220, 5, 5, 20,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 19, HDMI_HDMI },
-	},
-	{
-		{ 1920, 540, 74250000, 44, 528, 148, 5, 2, 15,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			true, },
-		{ 20, HDMI_HDMI },
-	},
-	{
-		{ 1440, 288, 27000000, 126, 24, 138, 3, 2, 19,
-			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
-			true, },
-		{ 21, HDMI_HDMI },
-	},
-	{
-		{ 1440, 576, 54000000, 128, 24, 136, 5, 5, 39,
-			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
-			false, },
-		{ 29, HDMI_HDMI },
-	},
-	{
-		{ 1920, 1080, 148500000, 44, 528, 148, 5, 4, 36,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 31, HDMI_HDMI },
-	},
-	{
-		{ 1920, 1080, 74250000, 44, 638, 148, 5, 4, 36,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 32, HDMI_HDMI },
-	},
-	{
-		{ 2880, 480, 108108000, 248, 64, 240, 6, 9, 30,
-			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
-			false, },
-		{ 35, HDMI_HDMI },
-	},
-	{
-		{ 2880, 576, 108000000, 256, 48, 272, 5, 5, 39,
-			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
-			false, },
-		{ 37, HDMI_HDMI },
-	},
-};
-
-static const struct hdmi_config vesa_timings[] = {
-/* VESA From Here */
-	{
-		{ 640, 480, 25175000, 96, 16, 48, 2, 11, 31,
-			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
-			false, },
-		{ 4, HDMI_DVI },
-	},
-	{
-		{ 800, 600, 40000000, 128, 40, 88, 4, 1, 23,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 9, HDMI_DVI },
-	},
-	{
-		{ 848, 480, 33750000, 112, 16, 112, 8, 6, 23,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 0xE, HDMI_DVI },
-	},
-	{
-		{ 1280, 768, 79500000, 128, 64, 192, 7, 3, 20,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
-			false, },
-		{ 0x17, HDMI_DVI },
-	},
-	{
-		{ 1280, 800, 83500000, 128, 72, 200, 6, 3, 22,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
-			false, },
-		{ 0x1C, HDMI_DVI },
-	},
-	{
-		{ 1360, 768, 85500000, 112, 64, 256, 6, 3, 18,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 0x27, HDMI_DVI },
-	},
-	{
-		{ 1280, 960, 108000000, 112, 96, 312, 3, 1, 36,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 0x20, HDMI_DVI },
-	},
-	{
-		{ 1280, 1024, 108000000, 112, 48, 248, 3, 1, 38,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 0x23, HDMI_DVI },
-	},
-	{
-		{ 1024, 768, 65000000, 136, 24, 160, 6, 3, 29,
-			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
-			false, },
-		{ 0x10, HDMI_DVI },
-	},
-	{
-		{ 1400, 1050, 121750000, 144, 88, 232, 4, 3, 32,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
-			false, },
-		{ 0x2A, HDMI_DVI },
-	},
-	{
-		{ 1440, 900, 106500000, 152, 80, 232, 6, 3, 25,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
-			false, },
-		{ 0x2F, HDMI_DVI },
-	},
-	{
-		{ 1680, 1050, 146250000, 176 , 104, 280, 6, 3, 30,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
-			false, },
-		{ 0x3A, HDMI_DVI },
-	},
-	{
-		{ 1366, 768, 85500000, 143, 70, 213, 3, 3, 24,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 0x51, HDMI_DVI },
-	},
-	{
-		{ 1920, 1080, 148500000, 44, 148, 80, 5, 4, 36,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 0x52, HDMI_DVI },
-	},
-	{
-		{ 1280, 768, 68250000, 32, 48, 80, 7, 3, 12,
-			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 0x16, HDMI_DVI },
-	},
-	{
-		{ 1400, 1050, 101000000, 32, 48, 80, 4, 3, 23,
-			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 0x29, HDMI_DVI },
-	},
-	{
-		{ 1680, 1050, 119000000, 32, 48, 80, 6, 3, 21,
-			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 0x39, HDMI_DVI },
-	},
-	{
-		{ 1280, 800, 79500000, 32, 48, 80, 6, 3, 14,
-			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 0x1B, HDMI_DVI },
-	},
-	{
-		{ 1280, 720, 74250000, 40, 110, 220, 5, 5, 20,
-			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 0x55, HDMI_DVI },
-	},
-	{
-		{ 1920, 1200, 154000000, 32, 48, 80, 6, 3, 26,
-			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
-			false, },
-		{ 0x44, HDMI_DVI },
-	},
-};
-
-const struct hdmi_config *hdmi_default_timing(void)
-{
-	return &vesa_timings[0];
-}
-
-static const struct hdmi_config *hdmi_find_timing(int code,
-			const struct hdmi_config *timings_arr, int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++) {
-		if (timings_arr[i].cm.code == code)
-			return &timings_arr[i];
-	}
-
-	return NULL;
-}
-
-const struct hdmi_config *hdmi_get_timings(int mode, int code)
-{
-	const struct hdmi_config *arr;
-	int len;
-
-	if (mode == HDMI_DVI) {
-		arr = vesa_timings;
-		len = ARRAY_SIZE(vesa_timings);
-	} else {
-		arr = cea_timings;
-		len = ARRAY_SIZE(cea_timings);
-	}
-
-	return hdmi_find_timing(code, arr, len);
-}
-
-static bool hdmi_timings_compare(struct omap_video_timings *timing1,
-			const struct omap_video_timings *timing2)
-{
-	int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
-
-	if ((DIV_ROUND_CLOSEST(timing2->pixelclock, 1000000) ==
-			DIV_ROUND_CLOSEST(timing1->pixelclock, 1000000)) &&
-		(timing2->x_res == timing1->x_res) &&
-		(timing2->y_res == timing1->y_res)) {
-
-		timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp;
-		timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp;
-		timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
-		timing1_vsync = timing1->vfp + timing1->vsw + timing1->vbp;
-
-		DSSDBG("timing1_hsync = %d timing1_vsync = %d"\
-			"timing2_hsync = %d timing2_vsync = %d\n",
-			timing1_hsync, timing1_vsync,
-			timing2_hsync, timing2_vsync);
-
-		if ((timing1_hsync == timing2_hsync) &&
-			(timing1_vsync == timing2_vsync)) {
-			return true;
-		}
-	}
-	return false;
-}
-
-struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
-{
-	int i;
-	struct hdmi_cm cm = {-1};
-	DSSDBG("hdmi_get_code\n");
-
-	for (i = 0; i < ARRAY_SIZE(cea_timings); i++) {
-		if (hdmi_timings_compare(timing, &cea_timings[i].timings)) {
-			cm = cea_timings[i].cm;
-			goto end;
-		}
-	}
-	for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) {
-		if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) {
-			cm = vesa_timings[i].cm;
-			goto end;
-		}
-	}
-
-end:
-	return cm;
-}
-
 int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep,
 	struct hdmi_phy_data *phy)
 {
diff --git a/drivers/video/fbdev/s3c2410fb.c b/drivers/video/fbdev/s3c2410fb.c
index 81af5a63e9e1..d68595dcc5fd 100644
--- a/drivers/video/fbdev/s3c2410fb.c
+++ b/drivers/video/fbdev/s3c2410fb.c
@@ -932,7 +932,7 @@ static int s3c24xxfb_probe(struct platform_device *pdev,
 		goto release_irq;
 	}
 
-	clk_enable(info->clk);
+	clk_prepare_enable(info->clk);
 	dprintk("got and enabled clock\n");
 
 	usleep_range(1000, 1100);
@@ -996,7 +996,7 @@ static int s3c24xxfb_probe(struct platform_device *pdev,
 free_video_memory:
 	s3c2410fb_unmap_video_memory(fbinfo);
 release_clock:
-	clk_disable(info->clk);
+	clk_disable_unprepare(info->clk);
 	clk_put(info->clk);
 release_irq:
 	free_irq(irq, info);
@@ -1038,7 +1038,7 @@ static int s3c2410fb_remove(struct platform_device *pdev)
 	s3c2410fb_unmap_video_memory(fbinfo);
 
 	if (info->clk) {
-		clk_disable(info->clk);
+		clk_disable_unprepare(info->clk);
 		clk_put(info->clk);
 		info->clk = NULL;
 	}
@@ -1070,7 +1070,7 @@ static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state)
 	 * before the clock goes off again (bjd) */
 
 	usleep_range(1000, 1100);
-	clk_disable(info->clk);
+	clk_disable_unprepare(info->clk);
 
 	return 0;
 }
@@ -1080,7 +1080,7 @@ static int s3c2410fb_resume(struct platform_device *dev)
 	struct fb_info	   *fbinfo = platform_get_drvdata(dev);
 	struct s3c2410fb_info *info = fbinfo->par;
 
-	clk_enable(info->clk);
+	clk_prepare_enable(info->clk);
 	usleep_range(1000, 1100);
 
 	s3c2410fb_init_registers(fbinfo);
diff --git a/drivers/video/fbdev/sis/init.c b/drivers/video/fbdev/sis/init.c
index bd40f5ecd901..dfe3eb769638 100644
--- a/drivers/video/fbdev/sis/init.c
+++ b/drivers/video/fbdev/sis/init.c
@@ -1511,7 +1511,7 @@ SiS_Get310DRAMType(struct SiS_Private *SiS_Pr)
       } else if(SiS_Pr->ChipType >= SIS_340) {
 	 /* TODO */
 	 data = 0;
-      } if(SiS_Pr->ChipType >= SIS_661) {
+      } else if(SiS_Pr->ChipType >= SIS_661) {
 	 if(SiS_Pr->SiS_ROMNew) {
 	    data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
 	 } else {
diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c
index 22ad028bf123..3f12a2dd959a 100644
--- a/drivers/video/fbdev/sis/sis_main.c
+++ b/drivers/video/fbdev/sis/sis_main.c
@@ -1572,10 +1572,6 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 	/* Adapt RGB settings */
 	sisfb_bpp_to_var(ivideo, var);
 
-	/* Sanity check for offsets */
-	if(var->xoffset < 0) var->xoffset = 0;
-	if(var->yoffset < 0) var->yoffset = 0;
-
 	if(var->xres > var->xres_virtual)
 		var->xres_virtual = var->xres;
 
diff --git a/include/linux/fb.h b/include/linux/fb.h
index b6bfda99add3..09bb7a18d287 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -553,7 +553,7 @@ static inline struct apertures_struct *alloc_apertures(unsigned int max_num) {
 #define fb_memcpy_fromfb sbus_memcpy_fromio
 #define fb_memcpy_tofb sbus_memcpy_toio
 
-#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) || defined(__bfin__)
+#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) || defined(__bfin__) || defined(__arm__)
 
 #define fb_readb __raw_readb
 #define fb_readw __raw_readw
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index fc06c5b5f12a..069dfca9549a 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -61,6 +61,7 @@ struct omap_overlay_manager;
 struct dss_lcd_mgr_config;
 struct snd_aes_iec958;
 struct snd_cea_861_aud_if;
+struct hdmi_avi_infoframe;
 
 enum omap_display_type {
 	OMAP_DISPLAY_TYPE_NONE		= 0,
@@ -631,6 +632,10 @@ struct omapdss_hdmi_ops {
 	int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
 	bool (*detect)(struct omap_dss_device *dssdev);
 
+	int (*set_hdmi_mode)(struct omap_dss_device *dssdev, bool hdmi_mode);
+	int (*set_infoframe)(struct omap_dss_device *dssdev,
+		const struct hdmi_avi_infoframe *avi);
+
 	/*
 	 * Note: These functions might sleep. Do not call while
 	 * holding a spinlock/readlock.
@@ -850,6 +855,10 @@ struct omap_dss_driver {
 	int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
 	bool (*detect)(struct omap_dss_device *dssdev);
 
+	int (*set_hdmi_mode)(struct omap_dss_device *dssdev, bool hdmi_mode);
+	int (*set_hdmi_infoframe)(struct omap_dss_device *dssdev,
+		const struct hdmi_avi_infoframe *avi);
+
 	/*
 	 * For display drivers that support audio. This encompasses
 	 * HDMI and DisplayPort at the moment.