drm: imx: Move imx-drm driver out of staging
authorPhilipp Zabel <p.zabel@pengutronix.de>
Mon, 24 Nov 2014 15:33:34 +0000 (16:33 +0100)
committerDave Airlie <airlied@redhat.com>
Tue, 25 Nov 2014 23:40:39 +0000 (09:40 +1000)
The imx-drm driver was put into staging mostly for the following reasons,
all of which have been addressed or superseded:
 - convert the irq driver to use linear irq domains
 - work out the device tree bindings, this lead to the common of_graph
   bindings being used
 - factor out common helper functions, this mostly resulted in the
   component framework and drm of_graph helpers.

Before adding new fixes, and certainly before adding new features,
move it into its proper place below drivers/gpu/drm.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Dave Airlie <airlied@redhat.com>
35 files changed:
Documentation/devicetree/bindings/drm/imx/fsl-imx-drm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/drm/imx/hdmi.txt [new file with mode: 0644]
Documentation/devicetree/bindings/drm/imx/ldb.txt [new file with mode: 0644]
Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt [deleted file]
Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt [deleted file]
Documentation/devicetree/bindings/staging/imx-drm/ldb.txt [deleted file]
drivers/gpu/drm/Kconfig
drivers/gpu/drm/Makefile
drivers/gpu/drm/imx/Kconfig [new file with mode: 0644]
drivers/gpu/drm/imx/Makefile [new file with mode: 0644]
drivers/gpu/drm/imx/imx-drm-core.c [new file with mode: 0644]
drivers/gpu/drm/imx/imx-drm.h [new file with mode: 0644]
drivers/gpu/drm/imx/imx-hdmi.c [new file with mode: 0644]
drivers/gpu/drm/imx/imx-hdmi.h [new file with mode: 0644]
drivers/gpu/drm/imx/imx-ldb.c [new file with mode: 0644]
drivers/gpu/drm/imx/imx-tve.c [new file with mode: 0644]
drivers/gpu/drm/imx/ipuv3-crtc.c [new file with mode: 0644]
drivers/gpu/drm/imx/ipuv3-plane.c [new file with mode: 0644]
drivers/gpu/drm/imx/ipuv3-plane.h [new file with mode: 0644]
drivers/gpu/drm/imx/parallel-display.c [new file with mode: 0644]
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/imx-drm/Kconfig [deleted file]
drivers/staging/imx-drm/Makefile [deleted file]
drivers/staging/imx-drm/TODO [deleted file]
drivers/staging/imx-drm/imx-drm-core.c [deleted file]
drivers/staging/imx-drm/imx-drm.h [deleted file]
drivers/staging/imx-drm/imx-hdmi.c [deleted file]
drivers/staging/imx-drm/imx-hdmi.h [deleted file]
drivers/staging/imx-drm/imx-ldb.c [deleted file]
drivers/staging/imx-drm/imx-tve.c [deleted file]
drivers/staging/imx-drm/ipuv3-crtc.c [deleted file]
drivers/staging/imx-drm/ipuv3-plane.c [deleted file]
drivers/staging/imx-drm/ipuv3-plane.h [deleted file]
drivers/staging/imx-drm/parallel-display.c [deleted file]

diff --git a/Documentation/devicetree/bindings/drm/imx/fsl-imx-drm.txt b/Documentation/devicetree/bindings/drm/imx/fsl-imx-drm.txt
new file mode 100644 (file)
index 0000000..e75f0e5
--- /dev/null
@@ -0,0 +1,83 @@
+Freescale i.MX DRM master device
+================================
+
+The freescale i.MX DRM master device is a virtual device needed to list all
+IPU or other display interface nodes that comprise the graphics subsystem.
+
+Required properties:
+- compatible: Should be "fsl,imx-display-subsystem"
+- ports: Should contain a list of phandles pointing to display interface ports
+  of IPU devices
+
+example:
+
+display-subsystem {
+       compatible = "fsl,display-subsystem";
+       ports = <&ipu_di0>;
+};
+
+
+Freescale i.MX IPUv3
+====================
+
+Required properties:
+- compatible: Should be "fsl,<chip>-ipu"
+- reg: should be register base and length as documented in the
+  datasheet
+- interrupts: Should contain sync interrupt and error interrupt,
+  in this order.
+- resets: phandle pointing to the system reset controller and
+          reset line index, see reset/fsl,imx-src.txt for details
+Optional properties:
+- port@[0-3]: Port nodes with endpoint definitions as defined in
+  Documentation/devicetree/bindings/media/video-interfaces.txt.
+  Ports 0 and 1 should correspond to CSI0 and CSI1,
+  ports 2 and 3 should correspond to DI0 and DI1, respectively.
+
+example:
+
+ipu: ipu@18000000 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       compatible = "fsl,imx53-ipu";
+       reg = <0x18000000 0x080000000>;
+       interrupts = <11 10>;
+       resets = <&src 2>;
+
+       ipu_di0: port@2 {
+               reg = <2>;
+
+               ipu_di0_disp0: endpoint {
+                       remote-endpoint = <&display_in>;
+               };
+       };
+};
+
+Parallel display support
+========================
+
+Required properties:
+- compatible: Should be "fsl,imx-parallel-display"
+Optional properties:
+- interface_pix_fmt: How this display is connected to the
+  display interface. Currently supported types: "rgb24", "rgb565", "bgr666"
+  and "lvds666".
+- edid: verbatim EDID data block describing attached display.
+- ddc: phandle describing the i2c bus handling the display data
+  channel
+- port: A port node with endpoint definitions as defined in
+  Documentation/devicetree/bindings/media/video-interfaces.txt.
+
+example:
+
+display@di0 {
+       compatible = "fsl,imx-parallel-display";
+       edid = [edid-data];
+       interface-pix-fmt = "rgb24";
+
+       port {
+               display_in: endpoint {
+                       remote-endpoint = <&ipu_di0_disp0>;
+               };
+       };
+};
diff --git a/Documentation/devicetree/bindings/drm/imx/hdmi.txt b/Documentation/devicetree/bindings/drm/imx/hdmi.txt
new file mode 100644 (file)
index 0000000..1b756cf
--- /dev/null
@@ -0,0 +1,58 @@
+Device-Tree bindings for HDMI Transmitter
+
+HDMI Transmitter
+================
+
+The HDMI Transmitter is a Synopsys DesignWare HDMI 1.4 TX controller IP
+with accompanying PHY IP.
+
+Required properties:
+ - #address-cells : should be <1>
+ - #size-cells : should be <0>
+ - compatible : should be "fsl,imx6q-hdmi" or "fsl,imx6dl-hdmi".
+ - gpr : should be <&gpr>.
+   The phandle points to the iomuxc-gpr region containing the HDMI
+   multiplexer control register.
+ - clocks, clock-names : phandles to the HDMI iahb and isrf clocks, as described
+   in Documentation/devicetree/bindings/clock/clock-bindings.txt and
+   Documentation/devicetree/bindings/clock/imx6q-clock.txt.
+ - port@[0-4]: Up to four port nodes with endpoint definitions as defined in
+   Documentation/devicetree/bindings/media/video-interfaces.txt,
+   corresponding to the four inputs to the HDMI multiplexer.
+
+Optional properties:
+ - ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
+
+example:
+
+       gpr: iomuxc-gpr@020e0000 {
+               /* ... */
+       };
+
+        hdmi: hdmi@0120000 {
+                #address-cells = <1>;
+                #size-cells = <0>;
+                compatible = "fsl,imx6q-hdmi";
+                reg = <0x00120000 0x9000>;
+                interrupts = <0 115 0x04>;
+                gpr = <&gpr>;
+                clocks = <&clks 123>, <&clks 124>;
+                clock-names = "iahb", "isfr";
+                ddc-i2c-bus = <&i2c2>;
+
+                port@0 {
+                        reg = <0>;
+
+                        hdmi_mux_0: endpoint {
+                                remote-endpoint = <&ipu1_di0_hdmi>;
+                        };
+                };
+
+                port@1 {
+                        reg = <1>;
+
+                        hdmi_mux_1: endpoint {
+                                remote-endpoint = <&ipu1_di1_hdmi>;
+                        };
+                };
+        };
diff --git a/Documentation/devicetree/bindings/drm/imx/ldb.txt b/Documentation/devicetree/bindings/drm/imx/ldb.txt
new file mode 100644 (file)
index 0000000..443bcb6
--- /dev/null
@@ -0,0 +1,122 @@
+Device-Tree bindings for LVDS Display Bridge (ldb)
+
+LVDS Display Bridge
+===================
+
+The LVDS Display Bridge device tree node contains up to two lvds-channel
+nodes describing each of the two LVDS encoder channels of the bridge.
+
+Required properties:
+ - #address-cells : should be <1>
+ - #size-cells : should be <0>
+ - compatible : should be "fsl,imx53-ldb" or "fsl,imx6q-ldb".
+                Both LDB versions are similar, but i.MX6 has an additional
+                multiplexer in the front to select any of the four IPU display
+                interfaces as input for each LVDS channel.
+ - gpr : should be <&gpr> on i.MX53 and i.MX6q.
+         The phandle points to the iomuxc-gpr region containing the LVDS
+         control register.
+- clocks, clock-names : phandles to the LDB divider and selector clocks and to
+                        the display interface selector clocks, as described in
+                        Documentation/devicetree/bindings/clock/clock-bindings.txt
+        The following clocks are expected on i.MX53:
+                "di0_pll" - LDB LVDS channel 0 mux
+                "di1_pll" - LDB LVDS channel 1 mux
+                "di0" - LDB LVDS channel 0 gate
+                "di1" - LDB LVDS channel 1 gate
+                "di0_sel" - IPU1 DI0 mux
+                "di1_sel" - IPU1 DI1 mux
+        On i.MX6q the following additional clocks are needed:
+                "di2_sel" - IPU2 DI0 mux
+                "di3_sel" - IPU2 DI1 mux
+        The needed clock numbers for each are documented in
+        Documentation/devicetree/bindings/clock/imx5-clock.txt, and in
+        Documentation/devicetree/bindings/clock/imx6q-clock.txt.
+
+Optional properties:
+ - pinctrl-names : should be "default" on i.MX53, not used on i.MX6q
+ - pinctrl-0 : a phandle pointing to LVDS pin settings on i.MX53,
+               not used on i.MX6q
+ - fsl,dual-channel : boolean. if it exists, only LVDS channel 0 should
+   be configured - one input will be distributed on both outputs in dual
+   channel mode
+
+LVDS Channel
+============
+
+Each LVDS Channel has to contain a display-timings node that describes the
+video timings for the connected LVDS display. For detailed information, also
+have a look at Documentation/devicetree/bindings/video/display-timing.txt.
+
+Required properties:
+ - reg : should be <0> or <1>
+ - fsl,data-mapping : should be "spwg" or "jeida"
+                      This describes how the color bits are laid out in the
+                      serialized LVDS signal.
+ - fsl,data-width : should be <18> or <24>
+ - port: A port node with endpoint definitions as defined in
+   Documentation/devicetree/bindings/media/video-interfaces.txt.
+   On i.MX5, the internal two-input-multiplexer is used.
+   Due to hardware limitations, only one port (port@[0,1])
+   can be used for each channel (lvds-channel@[0,1], respectively)
+   On i.MX6, there should be four ports (port@[0-3]) that correspond
+   to the four LVDS multiplexer inputs.
+
+example:
+
+gpr: iomuxc-gpr@53fa8000 {
+       /* ... */
+};
+
+ldb: ldb@53fa8008 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       compatible = "fsl,imx53-ldb";
+       gpr = <&gpr>;
+       clocks = <&clks 122>, <&clks 120>,
+                <&clks 115>, <&clks 116>,
+                <&clks 123>, <&clks 85>;
+       clock-names = "di0_pll", "di1_pll",
+                     "di0_sel", "di1_sel",
+                     "di0", "di1";
+
+       lvds-channel@0 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0>;
+               fsl,data-mapping = "spwg";
+               fsl,data-width = <24>;
+
+               display-timings {
+                       /* ... */
+               };
+
+               port@0 {
+                       reg = <0>;
+
+                       lvds0_in: endpoint {
+                               remote-endpoint = <&ipu_di0_lvds0>;
+                       };
+               };
+       };
+
+       lvds-channel@1 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <1>;
+               fsl,data-mapping = "spwg";
+               fsl,data-width = <24>;
+
+               display-timings {
+                       /* ... */
+               };
+
+               port@1 {
+                       reg = <1>;
+
+                       lvds1_in: endpoint {
+                               remote-endpoint = <&ipu_di1_lvds1>;
+                       };
+               };
+       };
+};
diff --git a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
deleted file mode 100644 (file)
index e75f0e5..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-Freescale i.MX DRM master device
-================================
-
-The freescale i.MX DRM master device is a virtual device needed to list all
-IPU or other display interface nodes that comprise the graphics subsystem.
-
-Required properties:
-- compatible: Should be "fsl,imx-display-subsystem"
-- ports: Should contain a list of phandles pointing to display interface ports
-  of IPU devices
-
-example:
-
-display-subsystem {
-       compatible = "fsl,display-subsystem";
-       ports = <&ipu_di0>;
-};
-
-
-Freescale i.MX IPUv3
-====================
-
-Required properties:
-- compatible: Should be "fsl,<chip>-ipu"
-- reg: should be register base and length as documented in the
-  datasheet
-- interrupts: Should contain sync interrupt and error interrupt,
-  in this order.
-- resets: phandle pointing to the system reset controller and
-          reset line index, see reset/fsl,imx-src.txt for details
-Optional properties:
-- port@[0-3]: Port nodes with endpoint definitions as defined in
-  Documentation/devicetree/bindings/media/video-interfaces.txt.
-  Ports 0 and 1 should correspond to CSI0 and CSI1,
-  ports 2 and 3 should correspond to DI0 and DI1, respectively.
-
-example:
-
-ipu: ipu@18000000 {
-       #address-cells = <1>;
-       #size-cells = <0>;
-       compatible = "fsl,imx53-ipu";
-       reg = <0x18000000 0x080000000>;
-       interrupts = <11 10>;
-       resets = <&src 2>;
-
-       ipu_di0: port@2 {
-               reg = <2>;
-
-               ipu_di0_disp0: endpoint {
-                       remote-endpoint = <&display_in>;
-               };
-       };
-};
-
-Parallel display support
-========================
-
-Required properties:
-- compatible: Should be "fsl,imx-parallel-display"
-Optional properties:
-- interface_pix_fmt: How this display is connected to the
-  display interface. Currently supported types: "rgb24", "rgb565", "bgr666"
-  and "lvds666".
-- edid: verbatim EDID data block describing attached display.
-- ddc: phandle describing the i2c bus handling the display data
-  channel
-- port: A port node with endpoint definitions as defined in
-  Documentation/devicetree/bindings/media/video-interfaces.txt.
-
-example:
-
-display@di0 {
-       compatible = "fsl,imx-parallel-display";
-       edid = [edid-data];
-       interface-pix-fmt = "rgb24";
-
-       port {
-               display_in: endpoint {
-                       remote-endpoint = <&ipu_di0_disp0>;
-               };
-       };
-};
diff --git a/Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt b/Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt
deleted file mode 100644 (file)
index 1b756cf..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-Device-Tree bindings for HDMI Transmitter
-
-HDMI Transmitter
-================
-
-The HDMI Transmitter is a Synopsys DesignWare HDMI 1.4 TX controller IP
-with accompanying PHY IP.
-
-Required properties:
- - #address-cells : should be <1>
- - #size-cells : should be <0>
- - compatible : should be "fsl,imx6q-hdmi" or "fsl,imx6dl-hdmi".
- - gpr : should be <&gpr>.
-   The phandle points to the iomuxc-gpr region containing the HDMI
-   multiplexer control register.
- - clocks, clock-names : phandles to the HDMI iahb and isrf clocks, as described
-   in Documentation/devicetree/bindings/clock/clock-bindings.txt and
-   Documentation/devicetree/bindings/clock/imx6q-clock.txt.
- - port@[0-4]: Up to four port nodes with endpoint definitions as defined in
-   Documentation/devicetree/bindings/media/video-interfaces.txt,
-   corresponding to the four inputs to the HDMI multiplexer.
-
-Optional properties:
- - ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
-
-example:
-
-       gpr: iomuxc-gpr@020e0000 {
-               /* ... */
-       };
-
-        hdmi: hdmi@0120000 {
-                #address-cells = <1>;
-                #size-cells = <0>;
-                compatible = "fsl,imx6q-hdmi";
-                reg = <0x00120000 0x9000>;
-                interrupts = <0 115 0x04>;
-                gpr = <&gpr>;
-                clocks = <&clks 123>, <&clks 124>;
-                clock-names = "iahb", "isfr";
-                ddc-i2c-bus = <&i2c2>;
-
-                port@0 {
-                        reg = <0>;
-
-                        hdmi_mux_0: endpoint {
-                                remote-endpoint = <&ipu1_di0_hdmi>;
-                        };
-                };
-
-                port@1 {
-                        reg = <1>;
-
-                        hdmi_mux_1: endpoint {
-                                remote-endpoint = <&ipu1_di1_hdmi>;
-                        };
-                };
-        };
diff --git a/Documentation/devicetree/bindings/staging/imx-drm/ldb.txt b/Documentation/devicetree/bindings/staging/imx-drm/ldb.txt
deleted file mode 100644 (file)
index 443bcb6..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-Device-Tree bindings for LVDS Display Bridge (ldb)
-
-LVDS Display Bridge
-===================
-
-The LVDS Display Bridge device tree node contains up to two lvds-channel
-nodes describing each of the two LVDS encoder channels of the bridge.
-
-Required properties:
- - #address-cells : should be <1>
- - #size-cells : should be <0>
- - compatible : should be "fsl,imx53-ldb" or "fsl,imx6q-ldb".
-                Both LDB versions are similar, but i.MX6 has an additional
-                multiplexer in the front to select any of the four IPU display
-                interfaces as input for each LVDS channel.
- - gpr : should be <&gpr> on i.MX53 and i.MX6q.
-         The phandle points to the iomuxc-gpr region containing the LVDS
-         control register.
-- clocks, clock-names : phandles to the LDB divider and selector clocks and to
-                        the display interface selector clocks, as described in
-                        Documentation/devicetree/bindings/clock/clock-bindings.txt
-        The following clocks are expected on i.MX53:
-                "di0_pll" - LDB LVDS channel 0 mux
-                "di1_pll" - LDB LVDS channel 1 mux
-                "di0" - LDB LVDS channel 0 gate
-                "di1" - LDB LVDS channel 1 gate
-                "di0_sel" - IPU1 DI0 mux
-                "di1_sel" - IPU1 DI1 mux
-        On i.MX6q the following additional clocks are needed:
-                "di2_sel" - IPU2 DI0 mux
-                "di3_sel" - IPU2 DI1 mux
-        The needed clock numbers for each are documented in
-        Documentation/devicetree/bindings/clock/imx5-clock.txt, and in
-        Documentation/devicetree/bindings/clock/imx6q-clock.txt.
-
-Optional properties:
- - pinctrl-names : should be "default" on i.MX53, not used on i.MX6q
- - pinctrl-0 : a phandle pointing to LVDS pin settings on i.MX53,
-               not used on i.MX6q
- - fsl,dual-channel : boolean. if it exists, only LVDS channel 0 should
-   be configured - one input will be distributed on both outputs in dual
-   channel mode
-
-LVDS Channel
-============
-
-Each LVDS Channel has to contain a display-timings node that describes the
-video timings for the connected LVDS display. For detailed information, also
-have a look at Documentation/devicetree/bindings/video/display-timing.txt.
-
-Required properties:
- - reg : should be <0> or <1>
- - fsl,data-mapping : should be "spwg" or "jeida"
-                      This describes how the color bits are laid out in the
-                      serialized LVDS signal.
- - fsl,data-width : should be <18> or <24>
- - port: A port node with endpoint definitions as defined in
-   Documentation/devicetree/bindings/media/video-interfaces.txt.
-   On i.MX5, the internal two-input-multiplexer is used.
-   Due to hardware limitations, only one port (port@[0,1])
-   can be used for each channel (lvds-channel@[0,1], respectively)
-   On i.MX6, there should be four ports (port@[0-3]) that correspond
-   to the four LVDS multiplexer inputs.
-
-example:
-
-gpr: iomuxc-gpr@53fa8000 {
-       /* ... */
-};
-
-ldb: ldb@53fa8008 {
-       #address-cells = <1>;
-       #size-cells = <0>;
-       compatible = "fsl,imx53-ldb";
-       gpr = <&gpr>;
-       clocks = <&clks 122>, <&clks 120>,
-                <&clks 115>, <&clks 116>,
-                <&clks 123>, <&clks 85>;
-       clock-names = "di0_pll", "di1_pll",
-                     "di0_sel", "di1_sel",
-                     "di0", "di1";
-
-       lvds-channel@0 {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               reg = <0>;
-               fsl,data-mapping = "spwg";
-               fsl,data-width = <24>;
-
-               display-timings {
-                       /* ... */
-               };
-
-               port@0 {
-                       reg = <0>;
-
-                       lvds0_in: endpoint {
-                               remote-endpoint = <&ipu_di0_lvds0>;
-                       };
-               };
-       };
-
-       lvds-channel@1 {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               reg = <1>;
-               fsl,data-mapping = "spwg";
-               fsl,data-width = <24>;
-
-               display-timings {
-                       /* ... */
-               };
-
-               port@1 {
-                       reg = <1>;
-
-                       lvds1_in: endpoint {
-                               remote-endpoint = <&ipu_di1_lvds1>;
-                       };
-               };
-       };
-};
index 37c5a6e..24c2d7c 100644 (file)
@@ -202,3 +202,5 @@ source "drivers/gpu/drm/panel/Kconfig"
 source "drivers/gpu/drm/sti/Kconfig"
 
 source "drivers/gpu/drm/amd/amdkfd/Kconfig"
+
+source "drivers/gpu/drm/imx/Kconfig"
index dd9d35b..47d8986 100644 (file)
@@ -62,6 +62,7 @@ obj-$(CONFIG_DRM_BOCHS) += bochs/
 obj-$(CONFIG_DRM_MSM) += msm/
 obj-$(CONFIG_DRM_TEGRA) += tegra/
 obj-$(CONFIG_DRM_STI) += sti/
+obj-$(CONFIG_DRM_IMX) += imx/
 obj-y                  += i2c/
 obj-y                  += panel/
 obj-y                  += bridge/
diff --git a/drivers/gpu/drm/imx/Kconfig b/drivers/gpu/drm/imx/Kconfig
new file mode 100644 (file)
index 0000000..82fb758
--- /dev/null
@@ -0,0 +1,53 @@
+config DRM_IMX
+       tristate "DRM Support for Freescale i.MX"
+       select DRM_KMS_HELPER
+       select DRM_KMS_FB_HELPER
+       select VIDEOMODE_HELPERS
+       select DRM_GEM_CMA_HELPER
+       select DRM_KMS_CMA_HELPER
+       depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM)
+       help
+         enable i.MX graphics support
+
+config DRM_IMX_FB_HELPER
+       tristate "provide legacy framebuffer /dev/fb0"
+       select DRM_KMS_CMA_HELPER
+       depends on DRM_IMX
+       help
+         The DRM framework can provide a legacy /dev/fb0 framebuffer
+         for your device. This is necessary to get a framebuffer console
+         and also for applications using the legacy framebuffer API
+
+config DRM_IMX_PARALLEL_DISPLAY
+       tristate "Support for parallel displays"
+       select DRM_PANEL
+       depends on DRM_IMX
+       select VIDEOMODE_HELPERS
+
+config DRM_IMX_TVE
+       tristate "Support for TV and VGA displays"
+       depends on DRM_IMX
+       select REGMAP_MMIO
+       help
+         Choose this to enable the internal Television Encoder (TVe)
+         found on i.MX53 processors.
+
+config DRM_IMX_LDB
+       tristate "Support for LVDS displays"
+       depends on DRM_IMX && MFD_SYSCON
+       help
+         Choose this to enable the internal LVDS Display Bridge (LDB)
+         found on i.MX53 and i.MX6 processors.
+
+config DRM_IMX_IPUV3
+       tristate "DRM Support for i.MX IPUv3"
+       depends on DRM_IMX
+       depends on IMX_IPUV3_CORE
+       help
+         Choose this if you have a i.MX5 or i.MX6 processor.
+
+config DRM_IMX_HDMI
+       tristate "Freescale i.MX DRM HDMI"
+       depends on DRM_IMX
+       help
+         Choose this if you want to use HDMI on i.MX6.
diff --git a/drivers/gpu/drm/imx/Makefile b/drivers/gpu/drm/imx/Makefile
new file mode 100644 (file)
index 0000000..582c438
--- /dev/null
@@ -0,0 +1,12 @@
+
+imxdrm-objs := imx-drm-core.o
+
+obj-$(CONFIG_DRM_IMX) += imxdrm.o
+
+obj-$(CONFIG_DRM_IMX_PARALLEL_DISPLAY) += parallel-display.o
+obj-$(CONFIG_DRM_IMX_TVE) += imx-tve.o
+obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o
+
+imx-ipuv3-crtc-objs  := ipuv3-crtc.o ipuv3-plane.o
+obj-$(CONFIG_DRM_IMX_IPUV3)    += imx-ipuv3-crtc.o
+obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
new file mode 100644 (file)
index 0000000..2f80072
--- /dev/null
@@ -0,0 +1,705 @@
+/*
+ * Freescale i.MX drm driver
+ *
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix
+ *
+ * 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.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <linux/component.h>
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/module.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <drm/drmP.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_plane_helper.h>
+
+#include "imx-drm.h"
+
+#define MAX_CRTC       4
+
+struct imx_drm_crtc;
+
+struct imx_drm_component {
+       struct device_node *of_node;
+       struct list_head list;
+};
+
+struct imx_drm_device {
+       struct drm_device                       *drm;
+       struct imx_drm_crtc                     *crtc[MAX_CRTC];
+       int                                     pipes;
+       struct drm_fbdev_cma                    *fbhelper;
+};
+
+struct imx_drm_crtc {
+       struct drm_crtc                         *crtc;
+       int                                     pipe;
+       struct imx_drm_crtc_helper_funcs        imx_drm_helper_funcs;
+       struct device_node                      *port;
+};
+
+static int legacyfb_depth = 16;
+module_param(legacyfb_depth, int, 0444);
+
+int imx_drm_crtc_id(struct imx_drm_crtc *crtc)
+{
+       return crtc->pipe;
+}
+EXPORT_SYMBOL_GPL(imx_drm_crtc_id);
+
+static void imx_drm_driver_lastclose(struct drm_device *drm)
+{
+#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER)
+       struct imx_drm_device *imxdrm = drm->dev_private;
+
+       if (imxdrm->fbhelper)
+               drm_fbdev_cma_restore_mode(imxdrm->fbhelper);
+#endif
+}
+
+static int imx_drm_driver_unload(struct drm_device *drm)
+{
+#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER)
+       struct imx_drm_device *imxdrm = drm->dev_private;
+#endif
+
+       drm_kms_helper_poll_fini(drm);
+
+#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER)
+       if (imxdrm->fbhelper)
+               drm_fbdev_cma_fini(imxdrm->fbhelper);
+#endif
+
+       component_unbind_all(drm->dev, drm);
+
+       drm_vblank_cleanup(drm);
+       drm_mode_config_cleanup(drm);
+
+       platform_set_drvdata(drm->platformdev, NULL);
+
+       return 0;
+}
+
+static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc)
+{
+       struct imx_drm_device *imxdrm = crtc->dev->dev_private;
+       unsigned i;
+
+       for (i = 0; i < MAX_CRTC; i++)
+               if (imxdrm->crtc[i] && imxdrm->crtc[i]->crtc == crtc)
+                       return imxdrm->crtc[i];
+
+       return NULL;
+}
+
+int imx_drm_panel_format_pins(struct drm_encoder *encoder,
+               u32 interface_pix_fmt, int hsync_pin, int vsync_pin)
+{
+       struct imx_drm_crtc_helper_funcs *helper;
+       struct imx_drm_crtc *imx_crtc;
+
+       imx_crtc = imx_drm_find_crtc(encoder->crtc);
+       if (!imx_crtc)
+               return -EINVAL;
+
+       helper = &imx_crtc->imx_drm_helper_funcs;
+       if (helper->set_interface_pix_fmt)
+               return helper->set_interface_pix_fmt(encoder->crtc,
+                               encoder->encoder_type, interface_pix_fmt,
+                               hsync_pin, vsync_pin);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(imx_drm_panel_format_pins);
+
+int imx_drm_panel_format(struct drm_encoder *encoder, u32 interface_pix_fmt)
+{
+       return imx_drm_panel_format_pins(encoder, interface_pix_fmt, 2, 3);
+}
+EXPORT_SYMBOL_GPL(imx_drm_panel_format);
+
+int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc)
+{
+       return drm_vblank_get(imx_drm_crtc->crtc->dev, imx_drm_crtc->pipe);
+}
+EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_get);
+
+void imx_drm_crtc_vblank_put(struct imx_drm_crtc *imx_drm_crtc)
+{
+       drm_vblank_put(imx_drm_crtc->crtc->dev, imx_drm_crtc->pipe);
+}
+EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_put);
+
+void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc)
+{
+       drm_handle_vblank(imx_drm_crtc->crtc->dev, imx_drm_crtc->pipe);
+}
+EXPORT_SYMBOL_GPL(imx_drm_handle_vblank);
+
+static int imx_drm_enable_vblank(struct drm_device *drm, int crtc)
+{
+       struct imx_drm_device *imxdrm = drm->dev_private;
+       struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[crtc];
+       int ret;
+
+       if (!imx_drm_crtc)
+               return -EINVAL;
+
+       if (!imx_drm_crtc->imx_drm_helper_funcs.enable_vblank)
+               return -ENOSYS;
+
+       ret = imx_drm_crtc->imx_drm_helper_funcs.enable_vblank(
+                       imx_drm_crtc->crtc);
+
+       return ret;
+}
+
+static void imx_drm_disable_vblank(struct drm_device *drm, int crtc)
+{
+       struct imx_drm_device *imxdrm = drm->dev_private;
+       struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[crtc];
+
+       if (!imx_drm_crtc)
+               return;
+
+       if (!imx_drm_crtc->imx_drm_helper_funcs.disable_vblank)
+               return;
+
+       imx_drm_crtc->imx_drm_helper_funcs.disable_vblank(imx_drm_crtc->crtc);
+}
+
+static void imx_drm_driver_preclose(struct drm_device *drm,
+               struct drm_file *file)
+{
+       int i;
+
+       if (!file->is_master)
+               return;
+
+       for (i = 0; i < MAX_CRTC; i++)
+               imx_drm_disable_vblank(drm, i);
+}
+
+static const struct file_operations imx_drm_driver_fops = {
+       .owner = THIS_MODULE,
+       .open = drm_open,
+       .release = drm_release,
+       .unlocked_ioctl = drm_ioctl,
+       .mmap = drm_gem_cma_mmap,
+       .poll = drm_poll,
+       .read = drm_read,
+       .llseek = noop_llseek,
+};
+
+void imx_drm_connector_destroy(struct drm_connector *connector)
+{
+       drm_connector_unregister(connector);
+       drm_connector_cleanup(connector);
+}
+EXPORT_SYMBOL_GPL(imx_drm_connector_destroy);
+
+void imx_drm_encoder_destroy(struct drm_encoder *encoder)
+{
+       drm_encoder_cleanup(encoder);
+}
+EXPORT_SYMBOL_GPL(imx_drm_encoder_destroy);
+
+static void imx_drm_output_poll_changed(struct drm_device *drm)
+{
+#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER)
+       struct imx_drm_device *imxdrm = drm->dev_private;
+
+       drm_fbdev_cma_hotplug_event(imxdrm->fbhelper);
+#endif
+}
+
+static struct drm_mode_config_funcs imx_drm_mode_config_funcs = {
+       .fb_create = drm_fb_cma_create,
+       .output_poll_changed = imx_drm_output_poll_changed,
+};
+
+/*
+ * Main DRM initialisation. This binds, initialises and registers
+ * with DRM the subcomponents of the driver.
+ */
+static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
+{
+       struct imx_drm_device *imxdrm;
+       struct drm_connector *connector;
+       int ret;
+
+       imxdrm = devm_kzalloc(drm->dev, sizeof(*imxdrm), GFP_KERNEL);
+       if (!imxdrm)
+               return -ENOMEM;
+
+       imxdrm->drm = drm;
+
+       drm->dev_private = imxdrm;
+
+       /*
+        * enable drm irq mode.
+        * - with irq_enabled = true, we can use the vblank feature.
+        *
+        * P.S. note that we wouldn't use drm irq handler but
+        *      just specific driver own one instead because
+        *      drm framework supports only one irq handler and
+        *      drivers can well take care of their interrupts
+        */
+       drm->irq_enabled = true;
+
+       /*
+        * set max width and height as default value(4096x4096).
+        * this value would be used to check framebuffer size limitation
+        * at drm_mode_addfb().
+        */
+       drm->mode_config.min_width = 64;
+       drm->mode_config.min_height = 64;
+       drm->mode_config.max_width = 4096;
+       drm->mode_config.max_height = 4096;
+       drm->mode_config.funcs = &imx_drm_mode_config_funcs;
+
+       drm_mode_config_init(drm);
+
+       ret = drm_vblank_init(drm, MAX_CRTC);
+       if (ret)
+               goto err_kms;
+
+       /*
+        * with vblank_disable_allowed = true, vblank interrupt will be
+        * disabled by drm timer once a current process gives up ownership
+        * of vblank event. (after drm_vblank_put function is called)
+        */
+       drm->vblank_disable_allowed = true;
+
+       platform_set_drvdata(drm->platformdev, drm);
+
+       /* Now try and bind all our sub-components */
+       ret = component_bind_all(drm->dev, drm);
+       if (ret)
+               goto err_vblank;
+
+       /*
+        * All components are now added, we can publish the connector sysfs
+        * entries to userspace.  This will generate hotplug events and so
+        * userspace will expect to be able to access DRM at this point.
+        */
+       list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
+               ret = drm_connector_register(connector);
+               if (ret) {
+                       dev_err(drm->dev,
+                               "[CONNECTOR:%d:%s] drm_connector_register failed: %d\n",
+                               connector->base.id,
+                               connector->name, ret);
+                       goto err_unbind;
+               }
+       }
+
+       /*
+        * All components are now initialised, so setup the fb helper.
+        * The fb helper takes copies of key hardware information, so the
+        * crtcs/connectors/encoders must not change after this point.
+        */
+#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER)
+       if (legacyfb_depth != 16 && legacyfb_depth != 32) {
+               dev_warn(drm->dev, "Invalid legacyfb_depth.  Defaulting to 16bpp\n");
+               legacyfb_depth = 16;
+       }
+       imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
+                               drm->mode_config.num_crtc, MAX_CRTC);
+       if (IS_ERR(imxdrm->fbhelper)) {
+               ret = PTR_ERR(imxdrm->fbhelper);
+               imxdrm->fbhelper = NULL;
+               goto err_unbind;
+       }
+#endif
+
+       drm_kms_helper_poll_init(drm);
+
+       return 0;
+
+err_unbind:
+       component_unbind_all(drm->dev, drm);
+err_vblank:
+       drm_vblank_cleanup(drm);
+err_kms:
+       drm_mode_config_cleanup(drm);
+
+       return ret;
+}
+
+/*
+ * imx_drm_add_crtc - add a new crtc
+ */
+int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
+               struct imx_drm_crtc **new_crtc,
+               const struct imx_drm_crtc_helper_funcs *imx_drm_helper_funcs,
+               struct device_node *port)
+{
+       struct imx_drm_device *imxdrm = drm->dev_private;
+       struct imx_drm_crtc *imx_drm_crtc;
+       int ret;
+
+       /*
+        * The vblank arrays are dimensioned by MAX_CRTC - we can't
+        * pass IDs greater than this to those functions.
+        */
+       if (imxdrm->pipes >= MAX_CRTC)
+               return -EINVAL;
+
+       if (imxdrm->drm->open_count)
+               return -EBUSY;
+
+       imx_drm_crtc = kzalloc(sizeof(*imx_drm_crtc), GFP_KERNEL);
+       if (!imx_drm_crtc)
+               return -ENOMEM;
+
+       imx_drm_crtc->imx_drm_helper_funcs = *imx_drm_helper_funcs;
+       imx_drm_crtc->pipe = imxdrm->pipes++;
+       imx_drm_crtc->port = port;
+       imx_drm_crtc->crtc = crtc;
+
+       imxdrm->crtc[imx_drm_crtc->pipe] = imx_drm_crtc;
+
+       *new_crtc = imx_drm_crtc;
+
+       ret = drm_mode_crtc_set_gamma_size(imx_drm_crtc->crtc, 256);
+       if (ret)
+               goto err_register;
+
+       drm_crtc_helper_add(crtc,
+                       imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs);
+
+       drm_crtc_init(drm, crtc,
+                       imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs);
+
+       return 0;
+
+err_register:
+       imxdrm->crtc[imx_drm_crtc->pipe] = NULL;
+       kfree(imx_drm_crtc);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(imx_drm_add_crtc);
+
+/*
+ * imx_drm_remove_crtc - remove a crtc
+ */
+int imx_drm_remove_crtc(struct imx_drm_crtc *imx_drm_crtc)
+{
+       struct imx_drm_device *imxdrm = imx_drm_crtc->crtc->dev->dev_private;
+
+       drm_crtc_cleanup(imx_drm_crtc->crtc);
+
+       imxdrm->crtc[imx_drm_crtc->pipe] = NULL;
+
+       kfree(imx_drm_crtc);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(imx_drm_remove_crtc);
+
+/*
+ * Find the DRM CRTC possible mask for the connected endpoint.
+ *
+ * The encoder possible masks are defined by their position in the
+ * mode_config crtc_list.  This means that CRTCs must not be added
+ * or removed once the DRM device has been fully initialised.
+ */
+static uint32_t imx_drm_find_crtc_mask(struct imx_drm_device *imxdrm,
+       struct device_node *endpoint)
+{
+       struct device_node *port;
+       unsigned i;
+
+       port = of_graph_get_remote_port(endpoint);
+       if (!port)
+               return 0;
+       of_node_put(port);
+
+       for (i = 0; i < MAX_CRTC; i++) {
+               struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[i];
+
+               if (imx_drm_crtc && imx_drm_crtc->port == port)
+                       return drm_crtc_mask(imx_drm_crtc->crtc);
+       }
+
+       return 0;
+}
+
+static struct device_node *imx_drm_of_get_next_endpoint(
+               const struct device_node *parent, struct device_node *prev)
+{
+       struct device_node *node = of_graph_get_next_endpoint(parent, prev);
+
+       of_node_put(prev);
+       return node;
+}
+
+int imx_drm_encoder_parse_of(struct drm_device *drm,
+       struct drm_encoder *encoder, struct device_node *np)
+{
+       struct imx_drm_device *imxdrm = drm->dev_private;
+       struct device_node *ep = NULL;
+       uint32_t crtc_mask = 0;
+       int i;
+
+       for (i = 0; ; i++) {
+               u32 mask;
+
+               ep = imx_drm_of_get_next_endpoint(np, ep);
+               if (!ep)
+                       break;
+
+               mask = imx_drm_find_crtc_mask(imxdrm, ep);
+
+               /*
+                * If we failed to find the CRTC(s) which this encoder is
+                * supposed to be connected to, it's because the CRTC has
+                * not been registered yet.  Defer probing, and hope that
+                * the required CRTC is added later.
+                */
+               if (mask == 0)
+                       return -EPROBE_DEFER;
+
+               crtc_mask |= mask;
+       }
+
+       of_node_put(ep);
+       if (i == 0)
+               return -ENOENT;
+
+       encoder->possible_crtcs = crtc_mask;
+
+       /* FIXME: this is the mask of outputs which can clone this output. */
+       encoder->possible_clones = ~0;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(imx_drm_encoder_parse_of);
+
+/*
+ * @node: device tree node containing encoder input ports
+ * @encoder: drm_encoder
+ */
+int imx_drm_encoder_get_mux_id(struct device_node *node,
+                              struct drm_encoder *encoder)
+{
+       struct imx_drm_crtc *imx_crtc = imx_drm_find_crtc(encoder->crtc);
+       struct device_node *ep = NULL;
+       struct of_endpoint endpoint;
+       struct device_node *port;
+       int ret;
+
+       if (!node || !imx_crtc)
+               return -EINVAL;
+
+       do {
+               ep = imx_drm_of_get_next_endpoint(node, ep);
+               if (!ep)
+                       break;
+
+               port = of_graph_get_remote_port(ep);
+               of_node_put(port);
+               if (port == imx_crtc->port) {
+                       ret = of_graph_parse_endpoint(ep, &endpoint);
+                       return ret ? ret : endpoint.port;
+               }
+       } while (ep);
+
+       return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(imx_drm_encoder_get_mux_id);
+
+static const struct drm_ioctl_desc imx_drm_ioctls[] = {
+       /* none so far */
+};
+
+static struct drm_driver imx_drm_driver = {
+       .driver_features        = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
+       .load                   = imx_drm_driver_load,
+       .unload                 = imx_drm_driver_unload,
+       .lastclose              = imx_drm_driver_lastclose,
+       .preclose               = imx_drm_driver_preclose,
+       .set_busid              = drm_platform_set_busid,
+       .gem_free_object        = drm_gem_cma_free_object,
+       .gem_vm_ops             = &drm_gem_cma_vm_ops,
+       .dumb_create            = drm_gem_cma_dumb_create,
+       .dumb_map_offset        = drm_gem_cma_dumb_map_offset,
+       .dumb_destroy           = drm_gem_dumb_destroy,
+
+       .prime_handle_to_fd     = drm_gem_prime_handle_to_fd,
+       .prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
+       .gem_prime_import       = drm_gem_prime_import,
+       .gem_prime_export       = drm_gem_prime_export,
+       .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
+       .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
+       .gem_prime_vmap         = drm_gem_cma_prime_vmap,
+       .gem_prime_vunmap       = drm_gem_cma_prime_vunmap,
+       .gem_prime_mmap         = drm_gem_cma_prime_mmap,
+       .get_vblank_counter     = drm_vblank_count,
+       .enable_vblank          = imx_drm_enable_vblank,
+       .disable_vblank         = imx_drm_disable_vblank,
+       .ioctls                 = imx_drm_ioctls,
+       .num_ioctls             = ARRAY_SIZE(imx_drm_ioctls),
+       .fops                   = &imx_drm_driver_fops,
+       .name                   = "imx-drm",
+       .desc                   = "i.MX DRM graphics",
+       .date                   = "20120507",
+       .major                  = 1,
+       .minor                  = 0,
+       .patchlevel             = 0,
+};
+
+static int compare_of(struct device *dev, void *data)
+{
+       struct device_node *np = data;
+
+       /* Special case for LDB, one device for two channels */
+       if (of_node_cmp(np->name, "lvds-channel") == 0) {
+               np = of_get_parent(np);
+               of_node_put(np);
+       }
+
+       return dev->of_node == np;
+}
+
+static int imx_drm_bind(struct device *dev)
+{
+       return drm_platform_init(&imx_drm_driver, to_platform_device(dev));
+}
+
+static void imx_drm_unbind(struct device *dev)
+{
+       drm_put_dev(dev_get_drvdata(dev));
+}
+
+static const struct component_master_ops imx_drm_ops = {
+       .bind = imx_drm_bind,
+       .unbind = imx_drm_unbind,
+};
+
+static int imx_drm_platform_probe(struct platform_device *pdev)
+{
+       struct device_node *ep, *port, *remote;
+       struct component_match *match = NULL;
+       int ret;
+       int i;
+
+       /*
+        * Bind the IPU display interface ports first, so that
+        * imx_drm_encoder_parse_of called from encoder .bind callbacks
+        * works as expected.
+        */
+       for (i = 0; ; i++) {
+               port = of_parse_phandle(pdev->dev.of_node, "ports", i);
+               if (!port)
+                       break;
+
+               component_match_add(&pdev->dev, &match, compare_of, port);
+       }
+
+       if (i == 0) {
+               dev_err(&pdev->dev, "missing 'ports' property\n");
+               return -ENODEV;
+       }
+
+       /* Then bind all encoders */
+       for (i = 0; ; i++) {
+               port = of_parse_phandle(pdev->dev.of_node, "ports", i);
+               if (!port)
+                       break;
+
+               for_each_child_of_node(port, ep) {
+                       remote = of_graph_get_remote_port_parent(ep);
+                       if (!remote || !of_device_is_available(remote)) {
+                               of_node_put(remote);
+                               continue;
+                       } else if (!of_device_is_available(remote->parent)) {
+                               dev_warn(&pdev->dev, "parent device of %s is not available\n",
+                                        remote->full_name);
+                               of_node_put(remote);
+                               continue;
+                       }
+
+                       component_match_add(&pdev->dev, &match, compare_of, remote);
+                       of_node_put(remote);
+               }
+               of_node_put(port);
+       }
+
+       ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+       if (ret)
+               return ret;
+
+       return component_master_add_with_match(&pdev->dev, &imx_drm_ops, match);
+}
+
+static int imx_drm_platform_remove(struct platform_device *pdev)
+{
+       component_master_del(&pdev->dev, &imx_drm_ops);
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int imx_drm_suspend(struct device *dev)
+{
+       struct drm_device *drm_dev = dev_get_drvdata(dev);
+
+       /* The drm_dev is NULL before .load hook is called */
+       if (drm_dev == NULL)
+               return 0;
+
+       drm_kms_helper_poll_disable(drm_dev);
+
+       return 0;
+}
+
+static int imx_drm_resume(struct device *dev)
+{
+       struct drm_device *drm_dev = dev_get_drvdata(dev);
+
+       if (drm_dev == NULL)
+               return 0;
+
+       drm_helper_resume_force_mode(drm_dev);
+       drm_kms_helper_poll_enable(drm_dev);
+
+       return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(imx_drm_pm_ops, imx_drm_suspend, imx_drm_resume);
+
+static const struct of_device_id imx_drm_dt_ids[] = {
+       { .compatible = "fsl,imx-display-subsystem", },
+       { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, imx_drm_dt_ids);
+
+static struct platform_driver imx_drm_pdrv = {
+       .probe          = imx_drm_platform_probe,
+       .remove         = imx_drm_platform_remove,
+       .driver         = {
+               .owner  = THIS_MODULE,
+               .name   = "imx-drm",
+               .pm     = &imx_drm_pm_ops,
+               .of_match_table = imx_drm_dt_ids,
+       },
+};
+module_platform_driver(imx_drm_pdrv);
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_DESCRIPTION("i.MX drm driver core");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/imx/imx-drm.h b/drivers/gpu/drm/imx/imx-drm.h
new file mode 100644 (file)
index 0000000..7453ae0
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef _IMX_DRM_H_
+#define _IMX_DRM_H_
+
+struct device_node;
+struct drm_crtc;
+struct drm_connector;
+struct drm_device;
+struct drm_display_mode;
+struct drm_encoder;
+struct drm_fbdev_cma;
+struct drm_framebuffer;
+struct imx_drm_crtc;
+struct platform_device;
+
+int imx_drm_crtc_id(struct imx_drm_crtc *crtc);
+
+struct imx_drm_crtc_helper_funcs {
+       int (*enable_vblank)(struct drm_crtc *crtc);
+       void (*disable_vblank)(struct drm_crtc *crtc);
+       int (*set_interface_pix_fmt)(struct drm_crtc *crtc, u32 encoder_type,
+                       u32 pix_fmt, int hsync_pin, int vsync_pin);
+       const struct drm_crtc_helper_funcs *crtc_helper_funcs;
+       const struct drm_crtc_funcs *crtc_funcs;
+};
+
+int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
+               struct imx_drm_crtc **new_crtc,
+               const struct imx_drm_crtc_helper_funcs *imx_helper_funcs,
+               struct device_node *port);
+int imx_drm_remove_crtc(struct imx_drm_crtc *);
+int imx_drm_init_drm(struct platform_device *pdev,
+               int preferred_bpp);
+int imx_drm_exit_drm(void);
+
+int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc);
+void imx_drm_crtc_vblank_put(struct imx_drm_crtc *imx_drm_crtc);
+void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc);
+
+void imx_drm_mode_config_init(struct drm_device *drm);
+
+struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb);
+
+int imx_drm_panel_format_pins(struct drm_encoder *encoder,
+               u32 interface_pix_fmt, int hsync_pin, int vsync_pin);
+int imx_drm_panel_format(struct drm_encoder *encoder,
+               u32 interface_pix_fmt);
+
+int imx_drm_encoder_get_mux_id(struct device_node *node,
+               struct drm_encoder *encoder);
+int imx_drm_encoder_parse_of(struct drm_device *drm,
+       struct drm_encoder *encoder, struct device_node *np);
+
+void imx_drm_connector_destroy(struct drm_connector *connector);
+void imx_drm_encoder_destroy(struct drm_encoder *encoder);
+
+#endif /* _IMX_DRM_H_ */
diff --git a/drivers/gpu/drm/imx/imx-hdmi.c b/drivers/gpu/drm/imx/imx-hdmi.c
new file mode 100644 (file)
index 0000000..aaec6b2
--- /dev/null
@@ -0,0 +1,1767 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ *
+ * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
+ * for SLISHDMI13T and SLIPHDMIT IP cores
+ *
+ * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ */
+
+#include <linux/component.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/hdmi.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/of_device.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_encoder_slave.h>
+#include <video/imx-ipu-v3.h>
+
+#include "imx-hdmi.h"
+#include "imx-drm.h"
+
+#define HDMI_EDID_LEN          512
+
+#define RGB                    0
+#define YCBCR444               1
+#define YCBCR422_16BITS                2
+#define YCBCR422_8BITS         3
+#define XVYCC444               4
+
+enum hdmi_datamap {
+       RGB444_8B = 0x01,
+       RGB444_10B = 0x03,
+       RGB444_12B = 0x05,
+       RGB444_16B = 0x07,
+       YCbCr444_8B = 0x09,
+       YCbCr444_10B = 0x0B,
+       YCbCr444_12B = 0x0D,
+       YCbCr444_16B = 0x0F,
+       YCbCr422_8B = 0x16,
+       YCbCr422_10B = 0x14,
+       YCbCr422_12B = 0x12,
+};
+
+enum imx_hdmi_devtype {
+       IMX6Q_HDMI,
+       IMX6DL_HDMI,
+};
+
+static const u16 csc_coeff_default[3][4] = {
+       { 0x2000, 0x0000, 0x0000, 0x0000 },
+       { 0x0000, 0x2000, 0x0000, 0x0000 },
+       { 0x0000, 0x0000, 0x2000, 0x0000 }
+};
+
+static const u16 csc_coeff_rgb_out_eitu601[3][4] = {
+       { 0x2000, 0x6926, 0x74fd, 0x010e },
+       { 0x2000, 0x2cdd, 0x0000, 0x7e9a },
+       { 0x2000, 0x0000, 0x38b4, 0x7e3b }
+};
+
+static const u16 csc_coeff_rgb_out_eitu709[3][4] = {
+       { 0x2000, 0x7106, 0x7a02, 0x00a7 },
+       { 0x2000, 0x3264, 0x0000, 0x7e6d },
+       { 0x2000, 0x0000, 0x3b61, 0x7e25 }
+};
+
+static const u16 csc_coeff_rgb_in_eitu601[3][4] = {
+       { 0x2591, 0x1322, 0x074b, 0x0000 },
+       { 0x6535, 0x2000, 0x7acc, 0x0200 },
+       { 0x6acd, 0x7534, 0x2000, 0x0200 }
+};
+
+static const u16 csc_coeff_rgb_in_eitu709[3][4] = {
+       { 0x2dc5, 0x0d9b, 0x049e, 0x0000 },
+       { 0x62f0, 0x2000, 0x7d11, 0x0200 },
+       { 0x6756, 0x78ab, 0x2000, 0x0200 }
+};
+
+struct hdmi_vmode {
+       bool mdvi;
+       bool mhsyncpolarity;
+       bool mvsyncpolarity;
+       bool minterlaced;
+       bool mdataenablepolarity;
+
+       unsigned int mpixelclock;
+       unsigned int mpixelrepetitioninput;
+       unsigned int mpixelrepetitionoutput;
+};
+
+struct hdmi_data_info {
+       unsigned int enc_in_format;
+       unsigned int enc_out_format;
+       unsigned int enc_color_depth;
+       unsigned int colorimetry;
+       unsigned int pix_repet_factor;
+       unsigned int hdcp_enable;
+       struct hdmi_vmode video_mode;
+};
+
+struct imx_hdmi {
+       struct drm_connector connector;
+       struct drm_encoder encoder;
+
+       enum imx_hdmi_devtype dev_type;
+       struct device *dev;
+       struct clk *isfr_clk;
+       struct clk *iahb_clk;
+
+       struct hdmi_data_info hdmi_data;
+       int vic;
+
+       u8 edid[HDMI_EDID_LEN];
+       bool cable_plugin;
+
+       bool phy_enabled;
+       struct drm_display_mode previous_mode;
+
+       struct regmap *regmap;
+       struct i2c_adapter *ddc;
+       void __iomem *regs;
+
+       unsigned int sample_rate;
+       int ratio;
+};
+
+static void imx_hdmi_set_ipu_di_mux(struct imx_hdmi *hdmi, int ipu_di)
+{
+       regmap_update_bits(hdmi->regmap, IOMUXC_GPR3,
+                          IMX6Q_GPR3_HDMI_MUX_CTL_MASK,
+                          ipu_di << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT);
+}
+
+static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset)
+{
+       writeb(val, hdmi->regs + offset);
+}
+
+static inline u8 hdmi_readb(struct imx_hdmi *hdmi, int offset)
+{
+       return readb(hdmi->regs + offset);
+}
+
+static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
+{
+       u8 val = hdmi_readb(hdmi, reg) & ~mask;
+
+       val |= data & mask;
+       hdmi_writeb(hdmi, val, reg);
+}
+
+static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg,
+                     u8 shift, u8 mask)
+{
+       hdmi_modb(hdmi, data << shift, mask, reg);
+}
+
+static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi,
+                                        unsigned int value)
+{
+       hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1);
+       hdmi_writeb(hdmi, (value >> 8) & 0xff, HDMI_AUD_N2);
+       hdmi_writeb(hdmi, (value >> 16) & 0x0f, HDMI_AUD_N3);
+
+       /* nshift factor = 0 */
+       hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);
+}
+
+static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts)
+{
+       /* Must be set/cleared first */
+       hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
+
+       hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1);
+       hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
+       hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
+                   HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
+}
+
+static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
+                                  unsigned int ratio)
+{
+       unsigned int n = (128 * freq) / 1000;
+
+       switch (freq) {
+       case 32000:
+               if (pixel_clk == 25170000)
+                       n = (ratio == 150) ? 9152 : 4576;
+               else if (pixel_clk == 27020000)
+                       n = (ratio == 150) ? 8192 : 4096;
+               else if (pixel_clk == 74170000 || pixel_clk == 148350000)
+                       n = 11648;
+               else
+                       n = 4096;
+               break;
+
+       case 44100:
+               if (pixel_clk == 25170000)
+                       n = 7007;
+               else if (pixel_clk == 74170000)
+                       n = 17836;
+               else if (pixel_clk == 148350000)
+                       n = (ratio == 150) ? 17836 : 8918;
+               else
+                       n = 6272;
+               break;
+
+       case 48000:
+               if (pixel_clk == 25170000)
+                       n = (ratio == 150) ? 9152 : 6864;
+               else if (pixel_clk == 27020000)
+                       n = (ratio == 150) ? 8192 : 6144;
+               else if (pixel_clk == 74170000)
+                       n = 11648;
+               else if (pixel_clk == 148350000)
+                       n = (ratio == 150) ? 11648 : 5824;
+               else
+                       n = 6144;
+               break;
+
+       case 88200:
+               n = hdmi_compute_n(44100, pixel_clk, ratio) * 2;
+               break;
+
+       case 96000:
+               n = hdmi_compute_n(48000, pixel_clk, ratio) * 2;
+               break;
+
+       case 176400:
+               n = hdmi_compute_n(44100, pixel_clk, ratio) * 4;
+               break;
+
+       case 192000:
+               n = hdmi_compute_n(48000, pixel_clk, ratio) * 4;
+               break;
+
+       default:
+               break;
+       }
+
+       return n;
+}
+
+static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
+                                    unsigned int ratio)
+{
+       unsigned int cts = 0;
+
+       pr_debug("%s: freq: %d pixel_clk: %ld ratio: %d\n", __func__, freq,
+                pixel_clk, ratio);
+
+       switch (freq) {
+       case 32000:
+               if (pixel_clk == 297000000) {
+                       cts = 222750;
+                       break;
+               }
+       case 48000:
+       case 96000:
+       case 192000:
+               switch (pixel_clk) {
+               case 25200000:
+               case 27000000:
+               case 54000000:
+               case 74250000:
+               case 148500000:
+                       cts = pixel_clk / 1000;
+                       break;
+               case 297000000:
+                       cts = 247500;
+                       break;
+               /*
+                * All other TMDS clocks are not supported by
+                * DWC_hdmi_tx. The TMDS clocks divided or
+                * multiplied by 1,001 coefficients are not
+                * supported.
+                */
+               default:
+                       break;
+               }
+               break;
+       case 44100:
+       case 88200:
+       case 176400:
+               switch (pixel_clk) {
+               case 25200000:
+                       cts = 28000;
+                       break;
+               case 27000000:
+                       cts = 30000;
+                       break;
+               case 54000000:
+                       cts = 60000;
+                       break;
+               case 74250000:
+                       cts = 82500;
+                       break;
+               case 148500000:
+                       cts = 165000;
+                       break;
+               case 297000000:
+                       cts = 247500;
+                       break;
+               default:
+                       break;
+               }
+               break;
+       default:
+               break;
+       }
+       if (ratio == 100)
+               return cts;
+       return (cts * ratio) / 100;
+}
+
+static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
+       unsigned long pixel_clk)
+{
+       unsigned int clk_n, clk_cts;
+
+       clk_n = hdmi_compute_n(hdmi->sample_rate, pixel_clk,
+                              hdmi->ratio);
+       clk_cts = hdmi_compute_cts(hdmi->sample_rate, pixel_clk,
+                                  hdmi->ratio);
+
+       if (!clk_cts) {
+               dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n",
+                        __func__, pixel_clk);
+               return;
+       }
+
+       dev_dbg(hdmi->dev, "%s: samplerate=%d  ratio=%d  pixelclk=%lu  N=%d cts=%d\n",
+               __func__, hdmi->sample_rate, hdmi->ratio,
+               pixel_clk, clk_n, clk_cts);
+
+       hdmi_set_clock_regenerator_n(hdmi, clk_n);
+       hdmi_regenerate_cts(hdmi, clk_cts);
+}
+
+static void hdmi_init_clk_regenerator(struct imx_hdmi *hdmi)
+{
+       hdmi_set_clk_regenerator(hdmi, 74250000);
+}
+
+static void hdmi_clk_regenerator_update_pixel_clock(struct imx_hdmi *hdmi)
+{
+       hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock);
+}
+
+/*
+ * this submodule is responsible for the video data synchronization.
+ * for example, for RGB 4:4:4 input, the data map is defined as
+ *                     pin{47~40} <==> R[7:0]
+ *                     pin{31~24} <==> G[7:0]
+ *                     pin{15~8}  <==> B[7:0]
+ */
+static void hdmi_video_sample(struct imx_hdmi *hdmi)
+{
+       int color_format = 0;
+       u8 val;
+
+       if (hdmi->hdmi_data.enc_in_format == RGB) {
+               if (hdmi->hdmi_data.enc_color_depth == 8)
+                       color_format = 0x01;
+               else if (hdmi->hdmi_data.enc_color_depth == 10)
+                       color_format = 0x03;
+               else if (hdmi->hdmi_data.enc_color_depth == 12)
+                       color_format = 0x05;
+               else if (hdmi->hdmi_data.enc_color_depth == 16)
+                       color_format = 0x07;
+               else
+                       return;
+       } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) {
+               if (hdmi->hdmi_data.enc_color_depth == 8)
+                       color_format = 0x09;
+               else if (hdmi->hdmi_data.enc_color_depth == 10)
+                       color_format = 0x0B;
+               else if (hdmi->hdmi_data.enc_color_depth == 12)
+                       color_format = 0x0D;
+               else if (hdmi->hdmi_data.enc_color_depth == 16)
+                       color_format = 0x0F;
+               else
+                       return;
+       } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) {
+               if (hdmi->hdmi_data.enc_color_depth == 8)
+                       color_format = 0x16;
+               else if (hdmi->hdmi_data.enc_color_depth == 10)
+                       color_format = 0x14;
+               else if (hdmi->hdmi_data.enc_color_depth == 12)
+                       color_format = 0x12;
+               else
+                       return;
+       }
+
+       val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
+               ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
+               HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
+       hdmi_writeb(hdmi, val, HDMI_TX_INVID0);
+
+       /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */
+       val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
+               HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
+               HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
+       hdmi_writeb(hdmi, val, HDMI_TX_INSTUFFING);
+       hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA0);
+       hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA1);
+       hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA0);
+       hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA1);
+       hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA0);
+       hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1);
+}
+
+static int is_color_space_conversion(struct imx_hdmi *hdmi)
+{
+       return hdmi->hdmi_data.enc_in_format != hdmi->hdmi_data.enc_out_format;
+}
+
+static int is_color_space_decimation(struct imx_hdmi *hdmi)
+{
+       if (hdmi->hdmi_data.enc_out_format != YCBCR422_8BITS)
+               return 0;
+       if (hdmi->hdmi_data.enc_in_format == RGB ||
+           hdmi->hdmi_data.enc_in_format == YCBCR444)
+               return 1;
+       return 0;
+}
+
+static int is_color_space_interpolation(struct imx_hdmi *hdmi)
+{
+       if (hdmi->hdmi_data.enc_in_format != YCBCR422_8BITS)
+               return 0;
+       if (hdmi->hdmi_data.enc_out_format == RGB ||
+           hdmi->hdmi_data.enc_out_format == YCBCR444)
+               return 1;
+       return 0;
+}
+
+static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
+{
+       const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
+       unsigned i;
+       u32 csc_scale = 1;
+
+       if (is_color_space_conversion(hdmi)) {
+               if (hdmi->hdmi_data.enc_out_format == RGB) {
+                       if (hdmi->hdmi_data.colorimetry ==
+                                       HDMI_COLORIMETRY_ITU_601)
+                               csc_coeff = &csc_coeff_rgb_out_eitu601;
+                       else
+                               csc_coeff = &csc_coeff_rgb_out_eitu709;
+               } else if (hdmi->hdmi_data.enc_in_format == RGB) {
+                       if (hdmi->hdmi_data.colorimetry ==
+                                       HDMI_COLORIMETRY_ITU_601)
+                               csc_coeff = &csc_coeff_rgb_in_eitu601;
+                       else
+                               csc_coeff = &csc_coeff_rgb_in_eitu709;
+                       csc_scale = 0;
+               }
+       }
+
+       /* The CSC registers are sequential, alternating MSB then LSB */
+       for (i = 0; i < ARRAY_SIZE(csc_coeff_default[0]); i++) {
+               u16 coeff_a = (*csc_coeff)[0][i];
+               u16 coeff_b = (*csc_coeff)[1][i];
+               u16 coeff_c = (*csc_coeff)[2][i];
+
+               hdmi_writeb(hdmi, coeff_a & 0xff,
+                       HDMI_CSC_COEF_A1_LSB + i * 2);
+               hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2);
+               hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2);
+               hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2);
+               hdmi_writeb(hdmi, coeff_c & 0xff,
+                       HDMI_CSC_COEF_C1_LSB + i * 2);
+               hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2);
+       }
+
+       hdmi_modb(hdmi, csc_scale, HDMI_CSC_SCALE_CSCSCALE_MASK,
+                 HDMI_CSC_SCALE);
+}
+
+static void hdmi_video_csc(struct imx_hdmi *hdmi)
+{
+       int color_depth = 0;
+       int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
+       int decimation = 0;
+
+       /* YCC422 interpolation to 444 mode */
+       if (is_color_space_interpolation(hdmi))
+               interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1;
+       else if (is_color_space_decimation(hdmi))
+               decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3;
+
+       if (hdmi->hdmi_data.enc_color_depth == 8)
+               color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP;
+       else if (hdmi->hdmi_data.enc_color_depth == 10)
+               color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP;
+       else if (hdmi->hdmi_data.enc_color_depth == 12)
+               color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP;
+       else if (hdmi->hdmi_data.enc_color_depth == 16)
+               color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP;
+       else
+               return;
+
+       /* Configure the CSC registers */
+       hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG);
+       hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK,
+                 HDMI_CSC_SCALE);
+
+       imx_hdmi_update_csc_coeffs(hdmi);
+}
+
+/*
+ * HDMI video packetizer is used to packetize the data.
+ * for example, if input is YCC422 mode or repeater is used,
+ * data should be repacked this module can be bypassed.
+ */
+static void hdmi_video_packetize(struct imx_hdmi *hdmi)
+{
+       unsigned int color_depth = 0;
+       unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit;
+       unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP;
+       struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
+       u8 val, vp_conf;
+
+       if (hdmi_data->enc_out_format == RGB
+               || hdmi_data->enc_out_format == YCBCR444) {
+               if (!hdmi_data->enc_color_depth)
+                       output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
+               else if (hdmi_data->enc_color_depth == 8) {
+                       color_depth = 4;
+                       output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
+               } else if (hdmi_data->enc_color_depth == 10)
+                       color_depth = 5;
+               else if (hdmi_data->enc_color_depth == 12)
+                       color_depth = 6;
+               else if (hdmi_data->enc_color_depth == 16)
+                       color_depth = 7;
+               else
+                       return;
+       } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) {
+               if (!hdmi_data->enc_color_depth ||
+                   hdmi_data->enc_color_depth == 8)
+                       remap_size = HDMI_VP_REMAP_YCC422_16bit;
+               else if (hdmi_data->enc_color_depth == 10)
+                       remap_size = HDMI_VP_REMAP_YCC422_20bit;
+               else if (hdmi_data->enc_color_depth == 12)
+                       remap_size = HDMI_VP_REMAP_YCC422_24bit;
+               else
+                       return;
+               output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
+       } else
+               return;
+
+       /* set the packetizer registers */
+       val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
+               HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
+               ((hdmi_data->pix_repet_factor <<
+               HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
+               HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
+       hdmi_writeb(hdmi, val, HDMI_VP_PR_CD);
+
+       hdmi_modb(hdmi, HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE,
+                 HDMI_VP_STUFF_PR_STUFFING_MASK, HDMI_VP_STUFF);
+
+       /* Data from pixel repeater block */
+       if (hdmi_data->pix_repet_factor > 1) {
+               vp_conf = HDMI_VP_CONF_PR_EN_ENABLE |
+                         HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER;
+       } else { /* data from packetizer block */
+               vp_conf = HDMI_VP_CONF_PR_EN_DISABLE |
+                         HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
+       }
+
+       hdmi_modb(hdmi, vp_conf,
+                 HDMI_VP_CONF_PR_EN_MASK |
+                 HDMI_VP_CONF_BYPASS_SELECT_MASK, HDMI_VP_CONF);
+
+       hdmi_modb(hdmi, 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET,
+                 HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, HDMI_VP_STUFF);
+
+       hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP);
+
+       if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) {
+               vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE |
+                         HDMI_VP_CONF_PP_EN_ENABLE |
+                         HDMI_VP_CONF_YCC422_EN_DISABLE;
+       } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) {
+               vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE |
+                         HDMI_VP_CONF_PP_EN_DISABLE |
+                         HDMI_VP_CONF_YCC422_EN_ENABLE;
+       } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) {
+               vp_conf = HDMI_VP_CONF_BYPASS_EN_ENABLE |
+                         HDMI_VP_CONF_PP_EN_DISABLE |
+                         HDMI_VP_CONF_YCC422_EN_DISABLE;
+       } else {
+               return;
+       }
+
+       hdmi_modb(hdmi, vp_conf,
+                 HDMI_VP_CONF_BYPASS_EN_MASK | HDMI_VP_CONF_PP_EN_ENMASK |
+                 HDMI_VP_CONF_YCC422_EN_MASK, HDMI_VP_CONF);
+
+       hdmi_modb(hdmi, HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
+                       HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE,
+                 HDMI_VP_STUFF_PP_STUFFING_MASK |
+                 HDMI_VP_STUFF_YCC422_STUFFING_MASK, HDMI_VP_STUFF);
+
+       hdmi_modb(hdmi, output_select, HDMI_VP_CONF_OUTPUT_SELECTOR_MASK,
+                 HDMI_VP_CONF);
+}
+
+static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi,
+                                               unsigned char bit)
+{
+       hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET,
+                 HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
+}
+
+static inline void hdmi_phy_test_enable(struct imx_hdmi *hdmi,
+                                               unsigned char bit)
+{
+       hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET,
+                 HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0);
+}
+
+static inline void hdmi_phy_test_clock(struct imx_hdmi *hdmi,
+                                               unsigned char bit)
+{
+       hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET,
+                 HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0);
+}
+
+static inline void hdmi_phy_test_din(struct imx_hdmi *hdmi,
+                                               unsigned char bit)
+{
+       hdmi_writeb(hdmi, bit, HDMI_PHY_TST1);
+}
+
+static inline void hdmi_phy_test_dout(struct imx_hdmi *hdmi,
+                                               unsigned char bit)
+{
+       hdmi_writeb(hdmi, bit, HDMI_PHY_TST2);
+}
+
+static bool hdmi_phy_wait_i2c_done(struct imx_hdmi *hdmi, int msec)
+{
+       while ((hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
+               if (msec-- == 0)
+                       return false;
+               udelay(1000);
+       }
+       return true;
+}
+
+static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
+                             unsigned char addr)
+{
+       hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0);
+       hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
+       hdmi_writeb(hdmi, (unsigned char)(data >> 8),
+               HDMI_PHY_I2CM_DATAO_1_ADDR);
+       hdmi_writeb(hdmi, (unsigned char)(data >> 0),
+               HDMI_PHY_I2CM_DATAO_0_ADDR);
+       hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
+               HDMI_PHY_I2CM_OPERATION_ADDR);
+       hdmi_phy_wait_i2c_done(hdmi, 1000);
+}
+
+static int hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
+                                    unsigned char addr)
+{
+       __hdmi_phy_i2c_write(hdmi, data, addr);
+       return 0;
+}
+
+static void imx_hdmi_phy_enable_power(struct imx_hdmi *hdmi, u8 enable)
+{
+       hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
+                        HDMI_PHY_CONF0_PDZ_OFFSET,
+                        HDMI_PHY_CONF0_PDZ_MASK);
+}
+
+static void imx_hdmi_phy_enable_tmds(struct imx_hdmi *hdmi, u8 enable)
+{
+       hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
+                        HDMI_PHY_CONF0_ENTMDS_OFFSET,
+                        HDMI_PHY_CONF0_ENTMDS_MASK);
+}
+
+static void imx_hdmi_phy_gen2_pddq(struct imx_hdmi *hdmi, u8 enable)
+{
+       hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
+                        HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
+                        HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
+}
+
+static void imx_hdmi_phy_gen2_txpwron(struct imx_hdmi *hdmi, u8 enable)
+{
+       hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
+                        HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
+                        HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
+}
+
+static void imx_hdmi_phy_sel_data_en_pol(struct imx_hdmi *hdmi, u8 enable)
+{
+       hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
+                        HDMI_PHY_CONF0_SELDATAENPOL_OFFSET,
+                        HDMI_PHY_CONF0_SELDATAENPOL_MASK);
+}
+
+static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable)
+{
+       hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
+                        HDMI_PHY_CONF0_SELDIPIF_OFFSET,
+                        HDMI_PHY_CONF0_SELDIPIF_MASK);
+}
+
+enum {
+       RES_8,
+       RES_10,
+       RES_12,
+       RES_MAX,
+};
+
+struct mpll_config {
+       unsigned long mpixelclock;
+       struct {
+               u16 cpce;
+               u16 gmp;
+       } res[RES_MAX];
+};
+
+static const struct mpll_config mpll_config[] = {
+       {
+               45250000, {
+                       { 0x01e0, 0x0000 },
+                       { 0x21e1, 0x0000 },
+                       { 0x41e2, 0x0000 }
+               },
+       }, {
+               92500000, {
+                       { 0x0140, 0x0005 },
+                       { 0x2141, 0x0005 },
+                       { 0x4142, 0x0005 },
+               },
+       }, {
+               148500000, {
+                       { 0x00a0, 0x000a },
+                       { 0x20a1, 0x000a },
+                       { 0x40a2, 0x000a },
+               },
+       }, {
+               ~0UL, {
+                       { 0x00a0, 0x000a },
+                       { 0x2001, 0x000f },
+                       { 0x4002, 0x000f },
+               },
+       }
+};
+
+struct curr_ctrl {
+       unsigned long mpixelclock;
+       u16 curr[RES_MAX];
+};
+
+static const struct curr_ctrl curr_ctrl[] = {
+       /*      pixelclk     bpp8    bpp10   bpp12 */
+       {
+                54000000, { 0x091c, 0x091c, 0x06dc },
+       }, {
+                58400000, { 0x091c, 0x06dc, 0x06dc },
+       }, {
+                72000000, { 0x06dc, 0x06dc, 0x091c },
+       }, {
+                74250000, { 0x06dc, 0x0b5c, 0x091c },
+       }, {
+               118800000, { 0x091c, 0x091c, 0x06dc },
+       }, {
+               216000000, { 0x06dc, 0x0b5c, 0x091c },
+       }
+};
+
+static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
+                             unsigned char res, int cscon)
+{
+       unsigned res_idx, i;
+       u8 val, msec;
+
+       if (prep)
+               return -EINVAL;
+
+       switch (res) {
+       case 0: /* color resolution 0 is 8 bit colour depth */
+       case 8:
+               res_idx = RES_8;
+               break;
+       case 10:
+               res_idx = RES_10;
+               break;
+       case 12:
+               res_idx = RES_12;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* Enable csc path */
+       if (cscon)
+               val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
+       else
+               val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;
+
+       hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL);
+
+       /* gen2 tx power off */
+       imx_hdmi_phy_gen2_txpwron(hdmi, 0);
+
+       /* gen2 pddq */
+       imx_hdmi_phy_gen2_pddq(hdmi, 1);
+
+       /* PHY reset */
+       hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
+       hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
+
+       hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
+
+       hdmi_phy_test_clear(hdmi, 1);
+       hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
+                       HDMI_PHY_I2CM_SLAVE_ADDR);
+       hdmi_phy_test_clear(hdmi, 0);
+
+       /* PLL/MPLL Cfg - always match on final entry */
+       for (i = 0; i < ARRAY_SIZE(mpll_config) - 1; i++)
+               if (hdmi->hdmi_data.video_mode.mpixelclock <=
+                   mpll_config[i].mpixelclock)
+                       break;
+
+       hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].cpce, 0x06);
+       hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].gmp, 0x15);
+
+       for (i = 0; i < ARRAY_SIZE(curr_ctrl); i++)
+               if (hdmi->hdmi_data.video_mode.mpixelclock <=
+                   curr_ctrl[i].mpixelclock)
+                       break;
+
+       if (i >= ARRAY_SIZE(curr_ctrl)) {
+               dev_err(hdmi->dev,
+                               "Pixel clock %d - unsupported by HDMI\n",
+                               hdmi->hdmi_data.video_mode.mpixelclock);
+               return -EINVAL;
+       }
+
+       /* CURRCTRL */
+       hdmi_phy_i2c_write(hdmi, curr_ctrl[i].curr[res_idx], 0x10);
+
+       hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);  /* PLLPHBYCTRL */
+       hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
+       /* RESISTANCE TERM 133Ohm Cfg */
+       hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);  /* TXTERM */
+       /* PREEMP Cgf 0.00 */
+       hdmi_phy_i2c_write(hdmi, 0x800d, 0x09);  /* CKSYMTXCTRL */
+       /* TX/CK LVL 10 */
+       hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E);  /* VLEVCTRL */
+       /* REMOVE CLK TERM */
+       hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);  /* CKCALCTRL */
+
+       imx_hdmi_phy_enable_power(hdmi, 1);
+
+       /* toggle TMDS enable */
+       imx_hdmi_phy_enable_tmds(hdmi, 0);
+       imx_hdmi_phy_enable_tmds(hdmi, 1);
+
+       /* gen2 tx power on */
+       imx_hdmi_phy_gen2_txpwron(hdmi, 1);
+       imx_hdmi_phy_gen2_pddq(hdmi, 0);
+
+       /*Wait for PHY PLL lock */
+       msec = 5;
+       do {
+               val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
+               if (!val)
+                       break;
+
+               if (msec == 0) {
+                       dev_err(hdmi->dev, "PHY PLL not locked\n");
+                       return -ETIMEDOUT;
+               }
+
+               udelay(1000);
+               msec--;
+       } while (1);
+
+       return 0;
+}
+
+static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
+{
+       int i, ret;
+       bool cscon = false;
+
+       /*check csc whether needed activated in HDMI mode */
+       cscon = (is_color_space_conversion(hdmi) &&
+                       !hdmi->hdmi_data.video_mode.mdvi);
+
+       /* HDMI Phy spec says to do the phy initialization sequence twice */
+       for (i = 0; i < 2; i++) {
+               imx_hdmi_phy_sel_data_en_pol(hdmi, 1);
+               imx_hdmi_phy_sel_interface_control(hdmi, 0);
+               imx_hdmi_phy_enable_tmds(hdmi, 0);
+               imx_hdmi_phy_enable_power(hdmi, 0);
+
+               /* Enable CSC */
+               ret = hdmi_phy_configure(hdmi, 0, 8, cscon);
+               if (ret)
+                       return ret;
+       }
+
+       hdmi->phy_enabled = true;
+       return 0;
+}
+
+static void hdmi_tx_hdcp_config(struct imx_hdmi *hdmi)
+{
+       u8 de;
+
+       if (hdmi->hdmi_data.video_mode.mdataenablepolarity)
+               de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH;
+       else
+               de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW;
+
+       /* disable rx detect */
+       hdmi_modb(hdmi, HDMI_A_HDCPCFG0_RXDETECT_DISABLE,
+                 HDMI_A_HDCPCFG0_RXDETECT_MASK, HDMI_A_HDCPCFG0);
+
+       hdmi_modb(hdmi, de, HDMI_A_VIDPOLCFG_DATAENPOL_MASK, HDMI_A_VIDPOLCFG);
+
+       hdmi_modb(hdmi, HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE,
+                 HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1);
+}
+
+static void hdmi_config_AVI(struct imx_hdmi *hdmi)
+{
+       u8 val, pix_fmt, under_scan;
+       u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry;
+       bool aspect_16_9;
+
+       aspect_16_9 = false; /* FIXME */
+
+       /* AVI Data Byte 1 */
+       if (hdmi->hdmi_data.enc_out_format == YCBCR444)
+               pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR444;
+       else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS)
+               pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR422;
+       else
+               pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB;
+
+               under_scan =  HDMI_FC_AVICONF0_SCAN_INFO_NODATA;
+
+       /*
+        * Active format identification data is present in the AVI InfoFrame.
+        * Under scan info, no bar data
+        */
+       val = pix_fmt | under_scan |
+               HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT |
+               HDMI_FC_AVICONF0_BAR_DATA_NO_DATA;
+
+       hdmi_writeb(hdmi, val, HDMI_FC_AVICONF0);
+
+       /* AVI Data Byte 2 -Set the Aspect Ratio */
+       if (aspect_16_9) {
+               act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9;
+               coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9;
+       } else {
+               act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3;
+               coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3;
+       }
+
+       /* Set up colorimetry */
+       if (hdmi->hdmi_data.enc_out_format == XVYCC444) {
+               colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO;
+               if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
+                       ext_colorimetry =
+                               HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
+               else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/
+                       ext_colorimetry =
+                               HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709;
+       } else if (hdmi->hdmi_data.enc_out_format != RGB) {
+               if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
+                       colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE;
+               else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/
+                       colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR;
+               ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
+       } else { /* Carries no data */
+               colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA;
+               ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
+       }
+
+       val = colorimetry | coded_ratio | act_ratio;
+       hdmi_writeb(hdmi, val, HDMI_FC_AVICONF1);
+
+       /* AVI Data Byte 3 */
+       val = HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA | ext_colorimetry |
+               HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT |
+               HDMI_FC_AVICONF2_SCALING_NONE;
+       hdmi_writeb(hdmi, val, HDMI_FC_AVICONF2);
+
+       /* AVI Data Byte 4 */
+       hdmi_writeb(hdmi, hdmi->vic, HDMI_FC_AVIVID);
+
+       /* AVI Data Byte 5- set up input and output pixel repetition */
+       val = (((hdmi->hdmi_data.video_mode.mpixelrepetitioninput + 1) <<
+               HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) &
+               HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) |
+               ((hdmi->hdmi_data.video_mode.mpixelrepetitionoutput <<
+               HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) &
+               HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK);
+       hdmi_writeb(hdmi, val, HDMI_FC_PRCONF);
+
+       /* IT Content and quantization range = don't care */
+       val = HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS |
+               HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED;
+       hdmi_writeb(hdmi, val, HDMI_FC_AVICONF3);
+
+       /* AVI Data Bytes 6-13 */
+       hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB0);
+       hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB1);
+       hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB0);
+       hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB1);
+       hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB0);
+       hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB1);
+       hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB0);
+       hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB1);
+}
+
+static void hdmi_av_composer(struct imx_hdmi *hdmi,
+                            const struct drm_display_mode *mode)
+{
+       u8 inv_val;
+       struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
+       int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
+
+       vmode->mhsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PHSYNC);
+       vmode->mvsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PVSYNC);
+       vmode->minterlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
+       vmode->mpixelclock = mode->clock * 1000;
+
+       dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
+
+       /* Set up HDMI_FC_INVIDCONF */
+       inv_val = (hdmi->hdmi_data.hdcp_enable ?
+               HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
+               HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE);
+
+       inv_val |= (vmode->mvsyncpolarity ?
+               HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
+               HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW);
+
+       inv_val |= (vmode->mhsyncpolarity ?
+               HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
+               HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW);
+
+       inv_val |= (vmode->mdataenablepolarity ?
+               HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
+               HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
+
+       if (hdmi->vic == 39)
+               inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH;
+       else
+               inv_val |= (vmode->minterlaced ?
+                       HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH :
+                       HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW);
+
+       inv_val |= (vmode->minterlaced ?
+               HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
+               HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE);
+
+       inv_val |= (vmode->mdvi ?
+               HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE :
+               HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE);
+
+       hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF);
+
+       /* Set up horizontal active pixel width */
+       hdmi_writeb(hdmi, mode->hdisplay >> 8, HDMI_FC_INHACTV1);
+       hdmi_writeb(hdmi, mode->hdisplay, HDMI_FC_INHACTV0);
+
+       /* Set up vertical active lines */
+       hdmi_writeb(hdmi, mode->vdisplay >> 8, HDMI_FC_INVACTV1);
+       hdmi_writeb(hdmi, mode->vdisplay, HDMI_FC_INVACTV0);
+
+       /* Set up horizontal blanking pixel region width */
+       hblank = mode->htotal - mode->hdisplay;
+       hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1);
+       hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0);
+
+       /* Set up vertical blanking pixel region width */
+       vblank = mode->vtotal - mode->vdisplay;
+       hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK);
+
+       /* Set up HSYNC active edge delay width (in pixel clks) */
+       h_de_hs = mode->hsync_start - mode->hdisplay;
+       hdmi_writeb(hdmi, h_de_hs >> 8, HDMI_FC_HSYNCINDELAY1);
+       hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0);
+
+       /* Set up VSYNC active edge delay (in lines) */
+       v_de_vs = mode->vsync_start - mode->vdisplay;
+       hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY);
+
+       /* Set up HSYNC active pulse width (in pixel clks) */
+       hsync_len = mode->hsync_end - mode->hsync_start;
+       hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1);
+       hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0);
+
+       /* Set up VSYNC active edge delay (in lines) */
+       vsync_len = mode->vsync_end - mode->vsync_start;
+       hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
+}
+
+static void imx_hdmi_phy_disable(struct imx_hdmi *hdmi)
+{
+       if (!hdmi->phy_enabled)
+               return;
+
+       imx_hdmi_phy_enable_tmds(hdmi, 0);
+       imx_hdmi_phy_enable_power(hdmi, 0);
+
+       hdmi->phy_enabled = false;
+}
+
+/* HDMI Initialization Step B.4 */
+static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi)
+{
+       u8 clkdis;
+
+       /* control period minimum duration */
+       hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
+       hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
+       hdmi_writeb(hdmi, 1, HDMI_FC_EXCTRLSPAC);
+
+       /* Set to fill TMDS data channels */
+       hdmi_writeb(hdmi, 0x0B, HDMI_FC_CH0PREAM);
+       hdmi_writeb(hdmi, 0x16, HDMI_FC_CH1PREAM);
+       hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
+
+       /* Enable pixel clock and tmds data path */
+       clkdis = 0x7F;
+       clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
+       hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
+
+       clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
+       hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
+
+       /* Enable csc path */
+       if (is_color_space_conversion(hdmi)) {
+               clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
+               hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
+       }
+}
+
+static void hdmi_enable_audio_clk(struct imx_hdmi *hdmi)
+{
+       hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
+}
+
+/* Workaround to clear the overflow condition */
+static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi)
+{
+       int count;
+       u8 val;
+
+       /* TMDS software reset */
+       hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
+
+       val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF);
+       if (hdmi->dev_type == IMX6DL_HDMI) {
+               hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
+               return;
+       }
+
+       for (count = 0; count < 4; count++)
+               hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
+}
+
+static void hdmi_enable_overflow_interrupts(struct imx_hdmi *hdmi)
+{
+       hdmi_writeb(hdmi, 0, HDMI_FC_MASK2);
+       hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2);
+}
+
+static void hdmi_disable_overflow_interrupts(struct imx_hdmi *hdmi)
+{
+       hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
+                   HDMI_IH_MUTE_FC_STAT2);
+}
+
+static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
+{
+       int ret;
+
+       hdmi_disable_overflow_interrupts(hdmi);
+
+       hdmi->vic = drm_match_cea_mode(mode);
+
+       if (!hdmi->vic) {
+               dev_dbg(hdmi->dev, "Non-CEA mode used in HDMI\n");
+               hdmi->hdmi_data.video_mode.mdvi = true;
+       } else {
+               dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic);
+               hdmi->hdmi_data.video_mode.mdvi = false;
+       }
+
+       if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
+               (hdmi->vic == 21) || (hdmi->vic == 22) ||
+               (hdmi->vic == 2) || (hdmi->vic == 3) ||
+               (hdmi->vic == 17) || (hdmi->vic == 18))
+               hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
+       else
+               hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
+
+       if ((hdmi->vic == 10) || (hdmi->vic == 11) ||
+               (hdmi->vic == 12) || (hdmi->vic == 13) ||
+               (hdmi->vic == 14) || (hdmi->vic == 15) ||
+               (hdmi->vic == 25) || (hdmi->vic == 26) ||
+               (hdmi->vic == 27) || (hdmi->vic == 28) ||
+               (hdmi->vic == 29) || (hdmi->vic == 30) ||
+               (hdmi->vic == 35) || (hdmi->vic == 36) ||
+               (hdmi->vic == 37) || (hdmi->vic == 38))
+               hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1;
+       else
+               hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
+
+       hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
+
+       /* TODO: Get input format from IPU (via FB driver interface) */
+       hdmi->hdmi_data.enc_in_format = RGB;
+
+       hdmi->hdmi_data.enc_out_format = RGB;
+
+       hdmi->hdmi_data.enc_color_depth = 8;
+       hdmi->hdmi_data.pix_repet_factor = 0;
+       hdmi->hdmi_data.hdcp_enable = 0;
+       hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
+
+       /* HDMI Initialization Step B.1 */
+       hdmi_av_composer(hdmi, mode);
+
+       /* HDMI Initializateion Step B.2 */
+       ret = imx_hdmi_phy_init(hdmi);
+       if (ret)
+               return ret;
+
+       /* HDMI Initialization Step B.3 */
+       imx_hdmi_enable_video_path(hdmi);
+
+       /* not for DVI mode */
+       if (hdmi->hdmi_data.video_mode.mdvi)
+               dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
+       else {
+               dev_dbg(hdmi->dev, "%s CEA mode\n", __func__);
+
+               /* HDMI Initialization Step E - Configure audio */
+               hdmi_clk_regenerator_update_pixel_clock(hdmi);
+               hdmi_enable_audio_clk(hdmi);
+
+               /* HDMI Initialization Step F - Configure AVI InfoFrame */
+               hdmi_config_AVI(hdmi);
+       }
+
+       hdmi_video_packetize(hdmi);
+       hdmi_video_csc(hdmi);
+       hdmi_video_sample(hdmi);
+       hdmi_tx_hdcp_config(hdmi);
+
+       imx_hdmi_clear_overflow(hdmi);
+       if (hdmi->cable_plugin && !hdmi->hdmi_data.video_mode.mdvi)
+               hdmi_enable_overflow_interrupts(hdmi);
+
+       return 0;
+}
+
+/* Wait until we are registered to enable interrupts */
+static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi)
+{
+       hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
+                   HDMI_PHY_I2CM_INT_ADDR);
+
+       hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
+                   HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
+                   HDMI_PHY_I2CM_CTLINT_ADDR);
+
+       /* enable cable hot plug irq */
+       hdmi_writeb(hdmi, (u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0);
+
+       /* Clear Hotplug interrupts */
+       hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
+
+       return 0;
+}
+
+static void initialize_hdmi_ih_mutes(struct imx_hdmi *hdmi)
+{
+       u8 ih_mute;
+
+       /*
+        * Boot up defaults are:
+        * HDMI_IH_MUTE   = 0x03 (disabled)
+        * HDMI_IH_MUTE_* = 0x00 (enabled)
+        *
+        * Disable top level interrupt bits in HDMI block
+        */
+       ih_mute = hdmi_readb(hdmi, HDMI_IH_MUTE) |
+                 HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
+                 HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;
+
+       hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
+
+       /* by default mask all interrupts */
+       hdmi_writeb(hdmi, 0xff, HDMI_VP_MASK);
+       hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK0);
+       hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK1);
+       hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK2);
+       hdmi_writeb(hdmi, 0xff, HDMI_PHY_MASK0);
+       hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_INT_ADDR);
+       hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_CTLINT_ADDR);
+       hdmi_writeb(hdmi, 0xff, HDMI_AUD_INT);
+       hdmi_writeb(hdmi, 0xff, HDMI_AUD_SPDIFINT);
+       hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
+       hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
+       hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
+       hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
+       hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
+       hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
+
+       /* Disable interrupts in the IH_MUTE_* registers */
+       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT0);
+       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT1);
+       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT2);
+       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AS_STAT0);
+       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_PHY_STAT0);
+       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CM_STAT0);
+       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_CEC_STAT0);
+       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_VP_STAT0);
+       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CMPHY_STAT0);
+       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
+
+       /* Enable top level interrupt bits in HDMI block */
+       ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
+                   HDMI_IH_MUTE_MUTE_ALL_INTERRUPT);
+       hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
+}
+
+static void imx_hdmi_poweron(struct imx_hdmi *hdmi)
+{
+       imx_hdmi_setup(hdmi, &hdmi->previous_mode);
+}
+
+static void imx_hdmi_poweroff(struct imx_hdmi *hdmi)
+{
+       imx_hdmi_phy_disable(hdmi);
+}
+
+static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector
+                                                       *connector, bool force)
+{
+       struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
+                                            connector);
+
+       return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
+               connector_status_connected : connector_status_disconnected;
+}
+
+static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
+{
+       struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
+                                            connector);
+       struct edid *edid;
+       int ret;
+
+       if (!hdmi->ddc)
+               return 0;
+
+       edid = drm_get_edid(connector, hdmi->ddc);
+       if (edid) {
+               dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
+                       edid->width_cm, edid->height_cm);
+
+               drm_mode_connector_update_edid_property(connector, edid);
+               ret = drm_add_edid_modes(connector, edid);
+               kfree(edid);
+       } else {
+               dev_dbg(hdmi->dev, "failed to get edid\n");
+       }
+
+       return 0;
+}
+
+static struct drm_encoder *imx_hdmi_connector_best_encoder(struct drm_connector
+                                                          *connector)
+{
+       struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
+                                            connector);
+
+       return &hdmi->encoder;
+}
+
+static void imx_hdmi_encoder_mode_set(struct drm_encoder *encoder,
+                       struct drm_display_mode *mode,
+                       struct drm_display_mode *adjusted_mode)
+{
+       struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
+
+       imx_hdmi_setup(hdmi, mode);
+
+       /* Store the display mode for plugin/DKMS poweron events */
+       memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
+}
+
+static bool imx_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
+                       const struct drm_display_mode *mode,
+                       struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+static void imx_hdmi_encoder_disable(struct drm_encoder *encoder)
+{
+}
+
+static void imx_hdmi_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+       struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
+
+       if (mode)
+               imx_hdmi_poweroff(hdmi);
+       else
+               imx_hdmi_poweron(hdmi);
+}
+
+static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder)
+{
+       struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
+
+       imx_hdmi_poweroff(hdmi);
+       imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24);
+}
+
+static void imx_hdmi_encoder_commit(struct drm_encoder *encoder)
+{
+       struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
+       int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
+
+       imx_hdmi_set_ipu_di_mux(hdmi, mux);
+
+       imx_hdmi_poweron(hdmi);
+}
+
+static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
+       .destroy = imx_drm_encoder_destroy,
+};
+
+static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = {
+       .dpms = imx_hdmi_encoder_dpms,
+       .prepare = imx_hdmi_encoder_prepare,
+       .commit = imx_hdmi_encoder_commit,
+       .mode_set = imx_hdmi_encoder_mode_set,
+       .mode_fixup = imx_hdmi_encoder_mode_fixup,
+       .disable = imx_hdmi_encoder_disable,
+};
+
+static struct drm_connector_funcs imx_hdmi_connector_funcs = {
+       .dpms = drm_helper_connector_dpms,
+       .fill_modes = drm_helper_probe_single_connector_modes,
+       .detect = imx_hdmi_connector_detect,
+       .destroy = imx_drm_connector_destroy,
+};
+
+static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = {
+       .get_modes = imx_hdmi_connector_get_modes,
+       .best_encoder = imx_hdmi_connector_best_encoder,
+};
+
+static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id)
+{
+       struct imx_hdmi *hdmi = dev_id;
+       u8 intr_stat;
+
+       intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
+       if (intr_stat)
+               hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
+
+       return intr_stat ? IRQ_WAKE_THREAD : IRQ_NONE;
+}
+
+static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
+{
+       struct imx_hdmi *hdmi = dev_id;
+       u8 intr_stat;
+       u8 phy_int_pol;
+
+       intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
+
+       phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0);
+
+       if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
+               if (phy_int_pol & HDMI_PHY_HPD) {
+                       dev_dbg(hdmi->dev, "EVENT=plugin\n");
+
+                       hdmi_modb(hdmi, 0, HDMI_PHY_HPD, HDMI_PHY_POL0);
+
+                       imx_hdmi_poweron(hdmi);
+               } else {
+                       dev_dbg(hdmi->dev, "EVENT=plugout\n");
+
+                       hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD,
+                               HDMI_PHY_POL0);
+
+                       imx_hdmi_poweroff(hdmi);
+               }
+               drm_helper_hpd_irq_event(hdmi->connector.dev);
+       }
+
+       hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
+       hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
+
+       return IRQ_HANDLED;
+}
+
+static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
+{
+       int ret;
+
+       ret = imx_drm_encoder_parse_of(drm, &hdmi->encoder,
+                                      hdmi->dev->of_node);
+       if (ret)
+               return ret;
+
+       hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
+
+       drm_encoder_helper_add(&hdmi->encoder, &imx_hdmi_encoder_helper_funcs);
+       drm_encoder_init(drm, &hdmi->encoder, &imx_hdmi_encoder_funcs,
+                        DRM_MODE_ENCODER_TMDS);
+
+       drm_connector_helper_add(&hdmi->connector,
+                       &imx_hdmi_connector_helper_funcs);
+       drm_connector_init(drm, &hdmi->connector, &imx_hdmi_connector_funcs,
+                          DRM_MODE_CONNECTOR_HDMIA);
+
+       hdmi->connector.encoder = &hdmi->encoder;
+
+       drm_mode_connector_attach_encoder(&hdmi->connector, &hdmi->encoder);
+
+       return 0;
+}
+
+static struct platform_device_id imx_hdmi_devtype[] = {
+       {
+               .name = "imx6q-hdmi",
+               .driver_data = IMX6Q_HDMI,
+       }, {
+               .name = "imx6dl-hdmi",
+               .driver_data = IMX6DL_HDMI,
+       }, { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype);
+
+static const struct of_device_id imx_hdmi_dt_ids[] = {
+{ .compatible = "fsl,imx6q-hdmi", .data = &imx_hdmi_devtype[IMX6Q_HDMI], },
+{ .compatible = "fsl,imx6dl-hdmi", .data = &imx_hdmi_devtype[IMX6DL_HDMI], },
+{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
+
+static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       const struct of_device_id *of_id =
+                               of_match_device(imx_hdmi_dt_ids, dev);
+       struct drm_device *drm = data;
+       struct device_node *np = dev->of_node;
+       struct device_node *ddc_node;
+       struct imx_hdmi *hdmi;
+       struct resource *iores;
+       int ret, irq;
+
+       hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
+       if (!hdmi)
+               return -ENOMEM;
+
+       hdmi->dev = dev;
+       hdmi->sample_rate = 48000;
+       hdmi->ratio = 100;
+
+       if (of_id) {
+               const struct platform_device_id *device_id = of_id->data;
+
+               hdmi->dev_type = device_id->driver_data;
+       }
+
+       ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
+       if (ddc_node) {
+               hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
+               if (!hdmi->ddc)
+                       dev_dbg(hdmi->dev, "failed to read ddc node\n");
+
+               of_node_put(ddc_node);
+       } else {
+               dev_dbg(hdmi->dev, "no ddc property found\n");
+       }
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0)
+               return irq;
+
+       ret = devm_request_threaded_irq(dev, irq, imx_hdmi_hardirq,
+                                       imx_hdmi_irq, IRQF_SHARED,
+                                       dev_name(dev), hdmi);
+       if (ret)
+               return ret;
+
+       iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       hdmi->regs = devm_ioremap_resource(dev, iores);
+       if (IS_ERR(hdmi->regs))
+               return PTR_ERR(hdmi->regs);
+
+       hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
+       if (IS_ERR(hdmi->regmap))
+               return PTR_ERR(hdmi->regmap);
+
+       hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
+       if (IS_ERR(hdmi->isfr_clk)) {
+               ret = PTR_ERR(hdmi->isfr_clk);
+               dev_err(hdmi->dev,
+                       "Unable to get HDMI isfr clk: %d\n", ret);
+               return ret;
+       }
+
+       ret = clk_prepare_enable(hdmi->isfr_clk);
+       if (ret) {
+               dev_err(hdmi->dev,
+                       "Cannot enable HDMI isfr clock: %d\n", ret);
+               return ret;
+       }
+
+       hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb");
+       if (IS_ERR(hdmi->iahb_clk)) {
+               ret = PTR_ERR(hdmi->iahb_clk);
+               dev_err(hdmi->dev,
+                       "Unable to get HDMI iahb clk: %d\n", ret);
+               goto err_isfr;
+       }
+
+       ret = clk_prepare_enable(hdmi->iahb_clk);
+       if (ret) {
+               dev_err(hdmi->dev,
+                       "Cannot enable HDMI iahb clock: %d\n", ret);
+               goto err_isfr;
+       }
+
+       /* Product and revision IDs */
+       dev_info(dev,
+               "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
+               hdmi_readb(hdmi, HDMI_DESIGN_ID),
+               hdmi_readb(hdmi, HDMI_REVISION_ID),
+               hdmi_readb(hdmi, HDMI_PRODUCT_ID0),
+               hdmi_readb(hdmi, HDMI_PRODUCT_ID1));
+
+       initialize_hdmi_ih_mutes(hdmi);
+
+       /*
+        * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
+        * N and cts values before enabling phy
+        */
+       hdmi_init_clk_regenerator(hdmi);
+
+       /*
+        * Configure registers related to HDMI interrupt
+        * generation before registering IRQ.
+        */
+       hdmi_writeb(hdmi, HDMI_PHY_HPD, HDMI_PHY_POL0);
+
+       /* Clear Hotplug interrupts */
+       hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
+
+       ret = imx_hdmi_fb_registered(hdmi);
+       if (ret)
+               goto err_iahb;
+
+       ret = imx_hdmi_register(drm, hdmi);
+       if (ret)
+               goto err_iahb;
+
+       /* Unmute interrupts */
+       hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
+
+       dev_set_drvdata(dev, hdmi);
+
+       return 0;
+
+err_iahb:
+       clk_disable_unprepare(hdmi->iahb_clk);
+err_isfr:
+       clk_disable_unprepare(hdmi->isfr_clk);
+
+       return ret;
+}
+
+static void imx_hdmi_unbind(struct device *dev, struct device *master,
+       void *data)
+{
+       struct imx_hdmi *hdmi = dev_get_drvdata(dev);
+
+       /* Disable all interrupts */
+       hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
+
+       hdmi->connector.funcs->destroy(&hdmi->connector);
+       hdmi->encoder.funcs->destroy(&hdmi->encoder);
+
+       clk_disable_unprepare(hdmi->iahb_clk);
+       clk_disable_unprepare(hdmi->isfr_clk);
+       i2c_put_adapter(hdmi->ddc);
+}
+
+static const struct component_ops hdmi_ops = {
+       .bind   = imx_hdmi_bind,
+       .unbind = imx_hdmi_unbind,
+};
+
+static int imx_hdmi_platform_probe(struct platform_device *pdev)
+{
+       return component_add(&pdev->dev, &hdmi_ops);
+}
+
+static int imx_hdmi_platform_remove(struct platform_device *pdev)
+{
+       component_del(&pdev->dev, &hdmi_ops);
+       return 0;
+}
+
+static struct platform_driver imx_hdmi_driver = {
+       .probe  = imx_hdmi_platform_probe,
+       .remove = imx_hdmi_platform_remove,
+       .driver = {
+               .name = "imx-hdmi",
+               .owner = THIS_MODULE,
+               .of_match_table = imx_hdmi_dt_ids,
+       },
+};
+
+module_platform_driver(imx_hdmi_driver);
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_DESCRIPTION("i.MX6 HDMI transmitter driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-hdmi");
diff --git a/drivers/gpu/drm/imx/imx-hdmi.h b/drivers/gpu/drm/imx/imx-hdmi.h
new file mode 100644 (file)
index 0000000..39b6776
--- /dev/null
@@ -0,0 +1,1032 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __IMX_HDMI_H__
+#define __IMX_HDMI_H__
+
+/* Identification Registers */
+#define HDMI_DESIGN_ID                          0x0000
+#define HDMI_REVISION_ID                        0x0001
+#define HDMI_PRODUCT_ID0                        0x0002
+#define HDMI_PRODUCT_ID1                        0x0003
+#define HDMI_CONFIG0_ID                         0x0004
+#define HDMI_CONFIG1_ID                         0x0005
+#define HDMI_CONFIG2_ID                         0x0006
+#define HDMI_CONFIG3_ID                         0x0007
+
+/* Interrupt Registers */
+#define HDMI_IH_FC_STAT0                        0x0100
+#define HDMI_IH_FC_STAT1                        0x0101
+#define HDMI_IH_FC_STAT2                        0x0102
+#define HDMI_IH_AS_STAT0                        0x0103
+#define HDMI_IH_PHY_STAT0                       0x0104
+#define HDMI_IH_I2CM_STAT0                      0x0105
+#define HDMI_IH_CEC_STAT0                       0x0106
+#define HDMI_IH_VP_STAT0                        0x0107
+#define HDMI_IH_I2CMPHY_STAT0                   0x0108
+#define HDMI_IH_AHBDMAAUD_STAT0                 0x0109
+
+#define HDMI_IH_MUTE_FC_STAT0                   0x0180
+#define HDMI_IH_MUTE_FC_STAT1                   0x0181
+#define HDMI_IH_MUTE_FC_STAT2                   0x0182
+#define HDMI_IH_MUTE_AS_STAT0                   0x0183
+#define HDMI_IH_MUTE_PHY_STAT0                  0x0184
+#define HDMI_IH_MUTE_I2CM_STAT0                 0x0185
+#define HDMI_IH_MUTE_CEC_STAT0                  0x0186
+#define HDMI_IH_MUTE_VP_STAT0                   0x0187
+#define HDMI_IH_MUTE_I2CMPHY_STAT0              0x0188
+#define HDMI_IH_MUTE_AHBDMAAUD_STAT0            0x0189
+#define HDMI_IH_MUTE                            0x01FF
+
+/* Video Sample Registers */
+#define HDMI_TX_INVID0                          0x0200
+#define HDMI_TX_INSTUFFING                      0x0201
+#define HDMI_TX_GYDATA0                         0x0202
+#define HDMI_TX_GYDATA1                         0x0203
+#define HDMI_TX_RCRDATA0                        0x0204
+#define HDMI_TX_RCRDATA1                        0x0205
+#define HDMI_TX_BCBDATA0                        0x0206
+#define HDMI_TX_BCBDATA1                        0x0207
+
+/* Video Packetizer Registers */
+#define HDMI_VP_STATUS                          0x0800
+#define HDMI_VP_PR_CD                           0x0801
+#define HDMI_VP_STUFF                           0x0802
+#define HDMI_VP_REMAP                           0x0803
+#define HDMI_VP_CONF                            0x0804
+#define HDMI_VP_STAT                            0x0805
+#define HDMI_VP_INT                             0x0806
+#define HDMI_VP_MASK                            0x0807
+#define HDMI_VP_POL                             0x0808
+
+/* Frame Composer Registers */
+#define HDMI_FC_INVIDCONF                       0x1000
+#define HDMI_FC_INHACTV0                        0x1001
+#define HDMI_FC_INHACTV1                        0x1002
+#define HDMI_FC_INHBLANK0                       0x1003
+#define HDMI_FC_INHBLANK1                       0x1004
+#define HDMI_FC_INVACTV0                        0x1005
+#define HDMI_FC_INVACTV1                        0x1006
+#define HDMI_FC_INVBLANK                        0x1007
+#define HDMI_FC_HSYNCINDELAY0                   0x1008
+#define HDMI_FC_HSYNCINDELAY1                   0x1009
+#define HDMI_FC_HSYNCINWIDTH0                   0x100A
+#define HDMI_FC_HSYNCINWIDTH1                   0x100B
+#define HDMI_FC_VSYNCINDELAY                    0x100C
+#define HDMI_FC_VSYNCINWIDTH                    0x100D
+#define HDMI_FC_INFREQ0                         0x100E
+#define HDMI_FC_INFREQ1                         0x100F
+#define HDMI_FC_INFREQ2                         0x1010
+#define HDMI_FC_CTRLDUR                         0x1011
+#define HDMI_FC_EXCTRLDUR                       0x1012
+#define HDMI_FC_EXCTRLSPAC                      0x1013
+#define HDMI_FC_CH0PREAM                        0x1014
+#define HDMI_FC_CH1PREAM                        0x1015
+#define HDMI_FC_CH2PREAM                        0x1016
+#define HDMI_FC_AVICONF3                        0x1017
+#define HDMI_FC_GCP                             0x1018
+#define HDMI_FC_AVICONF0                        0x1019
+#define HDMI_FC_AVICONF1                        0x101A
+#define HDMI_FC_AVICONF2                        0x101B
+#define HDMI_FC_AVIVID                          0x101C
+#define HDMI_FC_AVIETB0                         0x101D
+#define HDMI_FC_AVIETB1                         0x101E
+#define HDMI_FC_AVISBB0                         0x101F
+#define HDMI_FC_AVISBB1                         0x1020
+#define HDMI_FC_AVIELB0                         0x1021
+#define HDMI_FC_AVIELB1                         0x1022
+#define HDMI_FC_AVISRB0                         0x1023
+#define HDMI_FC_AVISRB1                         0x1024
+#define HDMI_FC_AUDICONF0                       0x1025
+#define HDMI_FC_AUDICONF1                       0x1026
+#define HDMI_FC_AUDICONF2                       0x1027
+#define HDMI_FC_AUDICONF3                       0x1028
+#define HDMI_FC_VSDIEEEID0                      0x1029
+#define HDMI_FC_VSDSIZE                         0x102A
+#define HDMI_FC_VSDIEEEID1                      0x1030
+#define HDMI_FC_VSDIEEEID2                      0x1031
+#define HDMI_FC_VSDPAYLOAD0                     0x1032
+#define HDMI_FC_VSDPAYLOAD1                     0x1033
+#define HDMI_FC_VSDPAYLOAD2                     0x1034
+#define HDMI_FC_VSDPAYLOAD3                     0x1035
+#define HDMI_FC_VSDPAYLOAD4                     0x1036
+#define HDMI_FC_VSDPAYLOAD5                     0x1037
+#define HDMI_FC_VSDPAYLOAD6                     0x1038
+#define HDMI_FC_VSDPAYLOAD7                     0x1039
+#define HDMI_FC_VSDPAYLOAD8                     0x103A
+#define HDMI_FC_VSDPAYLOAD9                     0x103B
+#define HDMI_FC_VSDPAYLOAD10                    0x103C
+#define HDMI_FC_VSDPAYLOAD11                    0x103D
+#define HDMI_FC_VSDPAYLOAD12                    0x103E
+#define HDMI_FC_VSDPAYLOAD13                    0x103F
+#define HDMI_FC_VSDPAYLOAD14                    0x1040
+#define HDMI_FC_VSDPAYLOAD15                    0x1041
+#define HDMI_FC_VSDPAYLOAD16                    0x1042
+#define HDMI_FC_VSDPAYLOAD17                    0x1043
+#define HDMI_FC_VSDPAYLOAD18                    0x1044
+#define HDMI_FC_VSDPAYLOAD19                    0x1045
+#define HDMI_FC_VSDPAYLOAD20                    0x1046
+#define HDMI_FC_VSDPAYLOAD21                    0x1047
+#define HDMI_FC_VSDPAYLOAD22                    0x1048
+#define HDMI_FC_VSDPAYLOAD23                    0x1049
+#define HDMI_FC_SPDVENDORNAME0                  0x104A
+#define HDMI_FC_SPDVENDORNAME1                  0x104B
+#define HDMI_FC_SPDVENDORNAME2                  0x104C
+#define HDMI_FC_SPDVENDORNAME3                  0x104D
+#define HDMI_FC_SPDVENDORNAME4                  0x104E
+#define HDMI_FC_SPDVENDORNAME5                  0x104F
+#define HDMI_FC_SPDVENDORNAME6                  0x1050
+#define HDMI_FC_SPDVENDORNAME7                  0x1051
+#define HDMI_FC_SDPPRODUCTNAME0                 0x1052
+#define HDMI_FC_SDPPRODUCTNAME1                 0x1053
+#define HDMI_FC_SDPPRODUCTNAME2                 0x1054
+#define HDMI_FC_SDPPRODUCTNAME3                 0x1055
+#define HDMI_FC_SDPPRODUCTNAME4                 0x1056
+#define HDMI_FC_SDPPRODUCTNAME5                 0x1057
+#define HDMI_FC_SDPPRODUCTNAME6                 0x1058
+#define HDMI_FC_SDPPRODUCTNAME7                 0x1059
+#define HDMI_FC_SDPPRODUCTNAME8                 0x105A
+#define HDMI_FC_SDPPRODUCTNAME9                 0x105B
+#define HDMI_FC_SDPPRODUCTNAME10                0x105C
+#define HDMI_FC_SDPPRODUCTNAME11                0x105D
+#define HDMI_FC_SDPPRODUCTNAME12                0x105E
+#define HDMI_FC_SDPPRODUCTNAME13                0x105F
+#define HDMI_FC_SDPPRODUCTNAME14                0x1060
+#define HDMI_FC_SPDPRODUCTNAME15                0x1061
+#define HDMI_FC_SPDDEVICEINF                    0x1062
+#define HDMI_FC_AUDSCONF                        0x1063
+#define HDMI_FC_AUDSSTAT                        0x1064
+#define HDMI_FC_DATACH0FILL                     0x1070
+#define HDMI_FC_DATACH1FILL                     0x1071
+#define HDMI_FC_DATACH2FILL                     0x1072
+#define HDMI_FC_CTRLQHIGH                       0x1073
+#define HDMI_FC_CTRLQLOW                        0x1074
+#define HDMI_FC_ACP0                            0x1075
+#define HDMI_FC_ACP28                           0x1076
+#define HDMI_FC_ACP27                           0x1077
+#define HDMI_FC_ACP26                           0x1078
+#define HDMI_FC_ACP25                           0x1079
+#define HDMI_FC_ACP24                           0x107A
+#define HDMI_FC_ACP23                           0x107B
+#define HDMI_FC_ACP22                           0x107C
+#define HDMI_FC_ACP21                           0x107D
+#define HDMI_FC_ACP20                           0x107E
+#define HDMI_FC_ACP19                           0x107F
+#define HDMI_FC_ACP18                           0x1080
+#define HDMI_FC_ACP17                           0x1081
+#define HDMI_FC_ACP16                           0x1082
+#define HDMI_FC_ACP15                           0x1083
+#define HDMI_FC_ACP14                           0x1084
+#define HDMI_FC_ACP13                           0x1085
+#define HDMI_FC_ACP12                           0x1086
+#define HDMI_FC_ACP11                           0x1087
+#define HDMI_FC_ACP10                           0x1088
+#define HDMI_FC_ACP9                            0x1089
+#define HDMI_FC_ACP8                            0x108A
+#define HDMI_FC_ACP7                            0x108B
+#define HDMI_FC_ACP6                            0x108C
+#define HDMI_FC_ACP5                            0x108D
+#define HDMI_FC_ACP4                            0x108E
+#define HDMI_FC_ACP3                            0x108F
+#define HDMI_FC_ACP2                            0x1090
+#define HDMI_FC_ACP1                            0x1091
+#define HDMI_FC_ISCR1_0                         0x1092
+#define HDMI_FC_ISCR1_16                        0x1093
+#define HDMI_FC_ISCR1_15                        0x1094
+#define HDMI_FC_ISCR1_14                        0x1095
+#define HDMI_FC_ISCR1_13                        0x1096
+#define HDMI_FC_ISCR1_12                        0x1097
+#define HDMI_FC_ISCR1_11                        0x1098
+#define HDMI_FC_ISCR1_10                        0x1099
+#define HDMI_FC_ISCR1_9                         0x109A
+#define HDMI_FC_ISCR1_8                         0x109B
+#define HDMI_FC_ISCR1_7                         0x109C
+#define HDMI_FC_ISCR1_6                         0x109D
+#define HDMI_FC_ISCR1_5                         0x109E
+#define HDMI_FC_ISCR1_4                         0x109F
+#define HDMI_FC_ISCR1_3                         0x10A0
+#define HDMI_FC_ISCR1_2                         0x10A1
+#define HDMI_FC_ISCR1_1                         0x10A2
+#define HDMI_FC_ISCR2_15                        0x10A3
+#define HDMI_FC_ISCR2_14                        0x10A4
+#define HDMI_FC_ISCR2_13                        0x10A5
+#define HDMI_FC_ISCR2_12                        0x10A6
+#define HDMI_FC_ISCR2_11                        0x10A7
+#define HDMI_FC_ISCR2_10                        0x10A8
+#define HDMI_FC_ISCR2_9                         0x10A9
+#define HDMI_FC_ISCR2_8                         0x10AA
+#define HDMI_FC_ISCR2_7                         0x10AB
+#define HDMI_FC_ISCR2_6                         0x10AC
+#define HDMI_FC_ISCR2_5                         0x10AD
+#define HDMI_FC_ISCR2_4                         0x10AE
+#define HDMI_FC_ISCR2_3                         0x10AF
+#define HDMI_FC_ISCR2_2                         0x10B0
+#define HDMI_FC_ISCR2_1                         0x10B1
+#define HDMI_FC_ISCR2_0                         0x10B2
+#define HDMI_FC_DATAUTO0                        0x10B3
+#define HDMI_FC_DATAUTO1                        0x10B4
+#define HDMI_FC_DATAUTO2                        0x10B5
+#define HDMI_FC_DATMAN                          0x10B6
+#define HDMI_FC_DATAUTO3                        0x10B7
+#define HDMI_FC_RDRB0                           0x10B8
+#define HDMI_FC_RDRB1                           0x10B9
+#define HDMI_FC_RDRB2                           0x10BA
+#define HDMI_FC_RDRB3                           0x10BB
+#define HDMI_FC_RDRB4                           0x10BC
+#define HDMI_FC_RDRB5                           0x10BD
+#define HDMI_FC_RDRB6                           0x10BE
+#define HDMI_FC_RDRB7                           0x10BF
+#define HDMI_FC_STAT0                           0x10D0
+#define HDMI_FC_INT0                            0x10D1
+#define HDMI_FC_MASK0                           0x10D2
+#define HDMI_FC_POL0                            0x10D3
+#define HDMI_FC_STAT1                           0x10D4
+#define HDMI_FC_INT1                            0x10D5
+#define HDMI_FC_MASK1                           0x10D6
+#define HDMI_FC_POL1                            0x10D7
+#define HDMI_FC_STAT2                           0x10D8
+#define HDMI_FC_INT2                            0x10D9
+#define HDMI_FC_MASK2                           0x10DA
+#define HDMI_FC_POL2                            0x10DB
+#define HDMI_FC_PRCONF                          0x10E0
+
+#define HDMI_FC_GMD_STAT                        0x1100
+#define HDMI_FC_GMD_EN                          0x1101
+#define HDMI_FC_GMD_UP                          0x1102
+#define HDMI_FC_GMD_CONF                        0x1103
+#define HDMI_FC_GMD_HB                          0x1104
+#define HDMI_FC_GMD_PB0                         0x1105
+#define HDMI_FC_GMD_PB1                         0x1106
+#define HDMI_FC_GMD_PB2                         0x1107
+#define HDMI_FC_GMD_PB3                         0x1108
+#define HDMI_FC_GMD_PB4                         0x1109
+#define HDMI_FC_GMD_PB5                         0x110A
+#define HDMI_FC_GMD_PB6                         0x110B
+#define HDMI_FC_GMD_PB7                         0x110C
+#define HDMI_FC_GMD_PB8                         0x110D
+#define HDMI_FC_GMD_PB9                         0x110E
+#define HDMI_FC_GMD_PB10                        0x110F
+#define HDMI_FC_GMD_PB11                        0x1110
+#define HDMI_FC_GMD_PB12                        0x1111
+#define HDMI_FC_GMD_PB13                        0x1112
+#define HDMI_FC_GMD_PB14                        0x1113
+#define HDMI_FC_GMD_PB15                        0x1114
+#define HDMI_FC_GMD_PB16                        0x1115
+#define HDMI_FC_GMD_PB17                        0x1116
+#define HDMI_FC_GMD_PB18                        0x1117
+#define HDMI_FC_GMD_PB19                        0x1118
+#define HDMI_FC_GMD_PB20                        0x1119
+#define HDMI_FC_GMD_PB21                        0x111A
+#define HDMI_FC_GMD_PB22                        0x111B
+#define HDMI_FC_GMD_PB23                        0x111C
+#define HDMI_FC_GMD_PB24                        0x111D
+#define HDMI_FC_GMD_PB25                        0x111E
+#define HDMI_FC_GMD_PB26                        0x111F
+#define HDMI_FC_GMD_PB27                        0x1120
+
+#define HDMI_FC_DBGFORCE                        0x1200
+#define HDMI_FC_DBGAUD0CH0                      0x1201
+#define HDMI_FC_DBGAUD1CH0                      0x1202
+#define HDMI_FC_DBGAUD2CH0                      0x1203
+#define HDMI_FC_DBGAUD0CH1                      0x1204
+#define HDMI_FC_DBGAUD1CH1                      0x1205
+#define HDMI_FC_DBGAUD2CH1                      0x1206
+#define HDMI_FC_DBGAUD0CH2                      0x1207
+#define HDMI_FC_DBGAUD1CH2                      0x1208
+#define HDMI_FC_DBGAUD2CH2                      0x1209
+#define HDMI_FC_DBGAUD0CH3                      0x120A
+#define HDMI_FC_DBGAUD1CH3                      0x120B
+#define HDMI_FC_DBGAUD2CH3                      0x120C
+#define HDMI_FC_DBGAUD0CH4                      0x120D
+#define HDMI_FC_DBGAUD1CH4                      0x120E
+#define HDMI_FC_DBGAUD2CH4                      0x120F
+#define HDMI_FC_DBGAUD0CH5                      0x1210
+#define HDMI_FC_DBGAUD1CH5                      0x1211
+#define HDMI_FC_DBGAUD2CH5                      0x1212
+#define HDMI_FC_DBGAUD0CH6                      0x1213
+#define HDMI_FC_DBGAUD1CH6                      0x1214
+#define HDMI_FC_DBGAUD2CH6                      0x1215
+#define HDMI_FC_DBGAUD0CH7                      0x1216
+#define HDMI_FC_DBGAUD1CH7                      0x1217
+#define HDMI_FC_DBGAUD2CH7                      0x1218
+#define HDMI_FC_DBGTMDS0                        0x1219
+#define HDMI_FC_DBGTMDS1                        0x121A
+#define HDMI_FC_DBGTMDS2                        0x121B
+
+/* HDMI Source PHY Registers */
+#define HDMI_PHY_CONF0                          0x3000
+#define HDMI_PHY_TST0                           0x3001
+#define HDMI_PHY_TST1                           0x3002
+#define HDMI_PHY_TST2                           0x3003
+#define HDMI_PHY_STAT0                          0x3004
+#define HDMI_PHY_INT0                           0x3005
+#define HDMI_PHY_MASK0                          0x3006
+#define HDMI_PHY_POL0                           0x3007
+
+/* HDMI Master PHY Registers */
+#define HDMI_PHY_I2CM_SLAVE_ADDR                0x3020
+#define HDMI_PHY_I2CM_ADDRESS_ADDR              0x3021
+#define HDMI_PHY_I2CM_DATAO_1_ADDR              0x3022
+#define HDMI_PHY_I2CM_DATAO_0_ADDR              0x3023
+#define HDMI_PHY_I2CM_DATAI_1_ADDR              0x3024
+#define HDMI_PHY_I2CM_DATAI_0_ADDR              0x3025
+#define HDMI_PHY_I2CM_OPERATION_ADDR            0x3026
+#define HDMI_PHY_I2CM_INT_ADDR                  0x3027
+#define HDMI_PHY_I2CM_CTLINT_ADDR               0x3028
+#define HDMI_PHY_I2CM_DIV_ADDR                  0x3029
+#define HDMI_PHY_I2CM_SOFTRSTZ_ADDR             0x302a
+#define HDMI_PHY_I2CM_SS_SCL_HCNT_1_ADDR        0x302b
+#define HDMI_PHY_I2CM_SS_SCL_HCNT_0_ADDR        0x302c
+#define HDMI_PHY_I2CM_SS_SCL_LCNT_1_ADDR        0x302d
+#define HDMI_PHY_I2CM_SS_SCL_LCNT_0_ADDR        0x302e
+#define HDMI_PHY_I2CM_FS_SCL_HCNT_1_ADDR        0x302f
+#define HDMI_PHY_I2CM_FS_SCL_HCNT_0_ADDR        0x3030
+#define HDMI_PHY_I2CM_FS_SCL_LCNT_1_ADDR        0x3031
+#define HDMI_PHY_I2CM_FS_SCL_LCNT_0_ADDR        0x3032
+
+/* Audio Sampler Registers */
+#define HDMI_AUD_CONF0                          0x3100
+#define HDMI_AUD_CONF1                          0x3101
+#define HDMI_AUD_INT                            0x3102
+#define HDMI_AUD_CONF2                          0x3103
+#define HDMI_AUD_N1                             0x3200
+#define HDMI_AUD_N2                             0x3201
+#define HDMI_AUD_N3                             0x3202
+#define HDMI_AUD_CTS1                           0x3203
+#define HDMI_AUD_CTS2                           0x3204
+#define HDMI_AUD_CTS3                           0x3205
+#define HDMI_AUD_INPUTCLKFS                     0x3206
+#define HDMI_AUD_SPDIFINT                      0x3302
+#define HDMI_AUD_CONF0_HBR                      0x3400
+#define HDMI_AUD_HBR_STATUS                     0x3401
+#define HDMI_AUD_HBR_INT                        0x3402
+#define HDMI_AUD_HBR_POL                        0x3403
+#define HDMI_AUD_HBR_MASK                       0x3404
+
+/*
+ * Generic Parallel Audio Interface Registers
+ * Not used as GPAUD interface is not enabled in hw
+ */
+#define HDMI_GP_CONF0                           0x3500
+#define HDMI_GP_CONF1                           0x3501
+#define HDMI_GP_CONF2                           0x3502
+#define HDMI_GP_STAT                            0x3503
+#define HDMI_GP_INT                             0x3504
+#define HDMI_GP_MASK                            0x3505
+#define HDMI_GP_POL                             0x3506
+
+/* Audio DMA Registers */
+#define HDMI_AHB_DMA_CONF0                      0x3600
+#define HDMI_AHB_DMA_START                      0x3601
+#define HDMI_AHB_DMA_STOP                       0x3602
+#define HDMI_AHB_DMA_THRSLD                     0x3603
+#define HDMI_AHB_DMA_STRADDR0                   0x3604
+#define HDMI_AHB_DMA_STRADDR1                   0x3605
+#define HDMI_AHB_DMA_STRADDR2                   0x3606
+#define HDMI_AHB_DMA_STRADDR3                   0x3607
+#define HDMI_AHB_DMA_STPADDR0                   0x3608
+#define HDMI_AHB_DMA_STPADDR1                   0x3609
+#define HDMI_AHB_DMA_STPADDR2                   0x360a
+#define HDMI_AHB_DMA_STPADDR3                   0x360b
+#define HDMI_AHB_DMA_BSTADDR0                   0x360c
+#define HDMI_AHB_DMA_BSTADDR1                   0x360d
+#define HDMI_AHB_DMA_BSTADDR2                   0x360e
+#define HDMI_AHB_DMA_BSTADDR3                   0x360f
+#define HDMI_AHB_DMA_MBLENGTH0                  0x3610
+#define HDMI_AHB_DMA_MBLENGTH1                  0x3611
+#define HDMI_AHB_DMA_STAT                       0x3612
+#define HDMI_AHB_DMA_INT                        0x3613
+#define HDMI_AHB_DMA_MASK                       0x3614
+#define HDMI_AHB_DMA_POL                        0x3615
+#define HDMI_AHB_DMA_CONF1                      0x3616
+#define HDMI_AHB_DMA_BUFFSTAT                   0x3617
+#define HDMI_AHB_DMA_BUFFINT                    0x3618
+#define HDMI_AHB_DMA_BUFFMASK                   0x3619
+#define HDMI_AHB_DMA_BUFFPOL                    0x361a
+
+/* Main Controller Registers */
+#define HDMI_MC_SFRDIV                          0x4000
+#define HDMI_MC_CLKDIS                          0x4001
+#define HDMI_MC_SWRSTZ                          0x4002
+#define HDMI_MC_OPCTRL                          0x4003
+#define HDMI_MC_FLOWCTRL                        0x4004
+#define HDMI_MC_PHYRSTZ                         0x4005
+#define HDMI_MC_LOCKONCLOCK                     0x4006
+#define HDMI_MC_HEACPHY_RST                     0x4007
+
+/* Color Space  Converter Registers */
+#define HDMI_CSC_CFG                            0x4100
+#define HDMI_CSC_SCALE                          0x4101
+#define HDMI_CSC_COEF_A1_MSB                    0x4102
+#define HDMI_CSC_COEF_A1_LSB                    0x4103
+#define HDMI_CSC_COEF_A2_MSB                    0x4104
+#define HDMI_CSC_COEF_A2_LSB                    0x4105
+#define HDMI_CSC_COEF_A3_MSB                    0x4106
+#define HDMI_CSC_COEF_A3_LSB                    0x4107
+#define HDMI_CSC_COEF_A4_MSB                    0x4108
+#define HDMI_CSC_COEF_A4_LSB                    0x4109
+#define HDMI_CSC_COEF_B1_MSB                    0x410A
+#define HDMI_CSC_COEF_B1_LSB                    0x410B
+#define HDMI_CSC_COEF_B2_MSB                    0x410C
+#define HDMI_CSC_COEF_B2_LSB                    0x410D
+#define HDMI_CSC_COEF_B3_MSB                    0x410E
+#define HDMI_CSC_COEF_B3_LSB                    0x410F
+#define HDMI_CSC_COEF_B4_MSB                    0x4110
+#define HDMI_CSC_COEF_B4_LSB                    0x4111
+#define HDMI_CSC_COEF_C1_MSB                    0x4112
+#define HDMI_CSC_COEF_C1_LSB                    0x4113
+#define HDMI_CSC_COEF_C2_MSB                    0x4114
+#define HDMI_CSC_COEF_C2_LSB                    0x4115
+#define HDMI_CSC_COEF_C3_MSB                    0x4116
+#define HDMI_CSC_COEF_C3_LSB                    0x4117
+#define HDMI_CSC_COEF_C4_MSB                    0x4118
+#define HDMI_CSC_COEF_C4_LSB                    0x4119
+
+/* HDCP Encryption Engine Registers */
+#define HDMI_A_HDCPCFG0                         0x5000
+#define HDMI_A_HDCPCFG1                         0x5001
+#define HDMI_A_HDCPOBS0                         0x5002
+#define HDMI_A_HDCPOBS1                         0x5003
+#define HDMI_A_HDCPOBS2                         0x5004
+#define HDMI_A_HDCPOBS3                         0x5005
+#define HDMI_A_APIINTCLR                        0x5006
+#define HDMI_A_APIINTSTAT                       0x5007
+#define HDMI_A_APIINTMSK                        0x5008
+#define HDMI_A_VIDPOLCFG                        0x5009
+#define HDMI_A_OESSWCFG                         0x500A
+#define HDMI_A_TIMER1SETUP0                     0x500B
+#define HDMI_A_TIMER1SETUP1                     0x500C
+#define HDMI_A_TIMER2SETUP0                     0x500D
+#define HDMI_A_TIMER2SETUP1                     0x500E
+#define HDMI_A_100MSCFG                         0x500F
+#define HDMI_A_2SCFG0                           0x5010
+#define HDMI_A_2SCFG1                           0x5011
+#define HDMI_A_5SCFG0                           0x5012
+#define HDMI_A_5SCFG1                           0x5013
+#define HDMI_A_SRMVERLSB                        0x5014
+#define HDMI_A_SRMVERMSB                        0x5015
+#define HDMI_A_SRMCTRL                          0x5016
+#define HDMI_A_SFRSETUP                         0x5017
+#define HDMI_A_I2CHSETUP                        0x5018
+#define HDMI_A_INTSETUP                         0x5019
+#define HDMI_A_PRESETUP                         0x501A
+#define HDMI_A_SRM_BASE                         0x5020
+
+/* CEC Engine Registers */
+#define HDMI_CEC_CTRL                           0x7D00
+#define HDMI_CEC_STAT                           0x7D01
+#define HDMI_CEC_MASK                           0x7D02
+#define HDMI_CEC_POLARITY                       0x7D03
+#define HDMI_CEC_INT                            0x7D04
+#define HDMI_CEC_ADDR_L                         0x7D05
+#define HDMI_CEC_ADDR_H                         0x7D06
+#define HDMI_CEC_TX_CNT                         0x7D07
+#define HDMI_CEC_RX_CNT                         0x7D08
+#define HDMI_CEC_TX_DATA0                       0x7D10
+#define HDMI_CEC_TX_DATA1                       0x7D11
+#define HDMI_CEC_TX_DATA2                       0x7D12
+#define HDMI_CEC_TX_DATA3                       0x7D13
+#define HDMI_CEC_TX_DATA4                       0x7D14
+#define HDMI_CEC_TX_DATA5                       0x7D15
+#define HDMI_CEC_TX_DATA6                       0x7D16
+#define HDMI_CEC_TX_DATA7                       0x7D17
+#define HDMI_CEC_TX_DATA8                       0x7D18
+#define HDMI_CEC_TX_DATA9                       0x7D19
+#define HDMI_CEC_TX_DATA10                      0x7D1a
+#define HDMI_CEC_TX_DATA11                      0x7D1b
+#define HDMI_CEC_TX_DATA12                      0x7D1c
+#define HDMI_CEC_TX_DATA13                      0x7D1d
+#define HDMI_CEC_TX_DATA14                      0x7D1e
+#define HDMI_CEC_TX_DATA15                      0x7D1f
+#define HDMI_CEC_RX_DATA0                       0x7D20
+#define HDMI_CEC_RX_DATA1                       0x7D21
+#define HDMI_CEC_RX_DATA2                       0x7D22
+#define HDMI_CEC_RX_DATA3                       0x7D23
+#define HDMI_CEC_RX_DATA4                       0x7D24
+#define HDMI_CEC_RX_DATA5                       0x7D25
+#define HDMI_CEC_RX_DATA6                       0x7D26
+#define HDMI_CEC_RX_DATA7                       0x7D27
+#define HDMI_CEC_RX_DATA8                       0x7D28
+#define HDMI_CEC_RX_DATA9                       0x7D29
+#define HDMI_CEC_RX_DATA10                      0x7D2a
+#define HDMI_CEC_RX_DATA11                      0x7D2b
+#define HDMI_CEC_RX_DATA12                      0x7D2c
+#define HDMI_CEC_RX_DATA13                      0x7D2d
+#define HDMI_CEC_RX_DATA14                      0x7D2e
+#define HDMI_CEC_RX_DATA15                      0x7D2f
+#define HDMI_CEC_LOCK                           0x7D30
+#define HDMI_CEC_WKUPCTRL                       0x7D31
+
+/* I2C Master Registers (E-DDC) */
+#define HDMI_I2CM_SLAVE                         0x7E00
+#define HDMI_I2CMESS                            0x7E01
+#define HDMI_I2CM_DATAO                         0x7E02
+#define HDMI_I2CM_DATAI                         0x7E03
+#define HDMI_I2CM_OPERATION                     0x7E04
+#define HDMI_I2CM_INT                           0x7E05
+#define HDMI_I2CM_CTLINT                        0x7E06
+#define HDMI_I2CM_DIV                           0x7E07
+#define HDMI_I2CM_SEGADDR                       0x7E08
+#define HDMI_I2CM_SOFTRSTZ                      0x7E09
+#define HDMI_I2CM_SEGPTR                        0x7E0A
+#define HDMI_I2CM_SS_SCL_HCNT_1_ADDR            0x7E0B
+#define HDMI_I2CM_SS_SCL_HCNT_0_ADDR            0x7E0C
+#define HDMI_I2CM_SS_SCL_LCNT_1_ADDR            0x7E0D
+#define HDMI_I2CM_SS_SCL_LCNT_0_ADDR            0x7E0E
+#define HDMI_I2CM_FS_SCL_HCNT_1_ADDR            0x7E0F
+#define HDMI_I2CM_FS_SCL_HCNT_0_ADDR            0x7E10
+#define HDMI_I2CM_FS_SCL_LCNT_1_ADDR            0x7E11
+#define HDMI_I2CM_FS_SCL_LCNT_0_ADDR            0x7E12
+
+enum {
+/* IH_FC_INT2 field values */
+       HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
+       HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
+       HDMI_IH_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* IH_FC_STAT2 field values */
+       HDMI_IH_FC_STAT2_OVERFLOW_MASK = 0x03,
+       HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
+       HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* IH_PHY_STAT0 field values */
+       HDMI_IH_PHY_STAT0_RX_SENSE3 = 0x20,
+       HDMI_IH_PHY_STAT0_RX_SENSE2 = 0x10,
+       HDMI_IH_PHY_STAT0_RX_SENSE1 = 0x8,
+       HDMI_IH_PHY_STAT0_RX_SENSE0 = 0x4,
+       HDMI_IH_PHY_STAT0_TX_PHY_LOCK = 0x2,
+       HDMI_IH_PHY_STAT0_HPD = 0x1,
+
+/* IH_MUTE_I2CMPHY_STAT0 field values */
+       HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYDONE = 0x2,
+       HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYERROR = 0x1,
+
+/* IH_AHBDMAAUD_STAT0 field values */
+       HDMI_IH_AHBDMAAUD_STAT0_ERROR = 0x20,
+       HDMI_IH_AHBDMAAUD_STAT0_LOST = 0x10,
+       HDMI_IH_AHBDMAAUD_STAT0_RETRY = 0x08,
+       HDMI_IH_AHBDMAAUD_STAT0_DONE = 0x04,
+       HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = 0x02,
+       HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01,
+
+/* IH_MUTE_FC_STAT2 field values */
+       HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK = 0x03,
+       HDMI_IH_MUTE_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
+       HDMI_IH_MUTE_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* IH_MUTE_AHBDMAAUD_STAT0 field values */
+       HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = 0x20,
+       HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = 0x10,
+       HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = 0x08,
+       HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = 0x04,
+       HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = 0x02,
+       HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01,
+
+/* IH_MUTE field values */
+       HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT = 0x2,
+       HDMI_IH_MUTE_MUTE_ALL_INTERRUPT = 0x1,
+
+/* TX_INVID0 field values */
+       HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_MASK = 0x80,
+       HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_ENABLE = 0x80,
+       HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE = 0x00,
+       HDMI_TX_INVID0_VIDEO_MAPPING_MASK = 0x1F,
+       HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET = 0,
+
+/* TX_INSTUFFING field values */
+       HDMI_TX_INSTUFFING_BDBDATA_STUFFING_MASK = 0x4,
+       HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE = 0x4,
+       HDMI_TX_INSTUFFING_BDBDATA_STUFFING_DISABLE = 0x0,
+       HDMI_TX_INSTUFFING_RCRDATA_STUFFING_MASK = 0x2,
+       HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE = 0x2,
+       HDMI_TX_INSTUFFING_RCRDATA_STUFFING_DISABLE = 0x0,
+       HDMI_TX_INSTUFFING_GYDATA_STUFFING_MASK = 0x1,
+       HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE = 0x1,
+       HDMI_TX_INSTUFFING_GYDATA_STUFFING_DISABLE = 0x0,
+
+/* VP_PR_CD field values */
+       HDMI_VP_PR_CD_COLOR_DEPTH_MASK = 0xF0,
+       HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET = 4,
+       HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK = 0x0F,
+       HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET = 0,
+
+/* VP_STUFF field values */
+       HDMI_VP_STUFF_IDEFAULT_PHASE_MASK = 0x20,
+       HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET = 5,
+       HDMI_VP_STUFF_IFIX_PP_TO_LAST_MASK = 0x10,
+       HDMI_VP_STUFF_IFIX_PP_TO_LAST_OFFSET = 4,
+       HDMI_VP_STUFF_ICX_GOTO_P0_ST_MASK = 0x8,
+       HDMI_VP_STUFF_ICX_GOTO_P0_ST_OFFSET = 3,
+       HDMI_VP_STUFF_YCC422_STUFFING_MASK = 0x4,
+       HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE = 0x4,
+       HDMI_VP_STUFF_YCC422_STUFFING_DIRECT_MODE = 0x0,
+       HDMI_VP_STUFF_PP_STUFFING_MASK = 0x2,
+       HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE = 0x2,
+       HDMI_VP_STUFF_PP_STUFFING_DIRECT_MODE = 0x0,
+       HDMI_VP_STUFF_PR_STUFFING_MASK = 0x1,
+       HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE = 0x1,
+       HDMI_VP_STUFF_PR_STUFFING_DIRECT_MODE = 0x0,
+
+/* VP_CONF field values */
+       HDMI_VP_CONF_BYPASS_EN_MASK = 0x40,
+       HDMI_VP_CONF_BYPASS_EN_ENABLE = 0x40,
+       HDMI_VP_CONF_BYPASS_EN_DISABLE = 0x00,
+       HDMI_VP_CONF_PP_EN_ENMASK = 0x20,
+       HDMI_VP_CONF_PP_EN_ENABLE = 0x20,
+       HDMI_VP_CONF_PP_EN_DISABLE = 0x00,
+       HDMI_VP_CONF_PR_EN_MASK = 0x10,
+       HDMI_VP_CONF_PR_EN_ENABLE = 0x10,
+       HDMI_VP_CONF_PR_EN_DISABLE = 0x00,
+       HDMI_VP_CONF_YCC422_EN_MASK = 0x8,
+       HDMI_VP_CONF_YCC422_EN_ENABLE = 0x8,
+       HDMI_VP_CONF_YCC422_EN_DISABLE = 0x0,
+       HDMI_VP_CONF_BYPASS_SELECT_MASK = 0x4,
+       HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER = 0x4,
+       HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER = 0x0,
+       HDMI_VP_CONF_OUTPUT_SELECTOR_MASK = 0x3,
+       HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS = 0x3,
+       HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422 = 0x1,
+       HDMI_VP_CONF_OUTPUT_SELECTOR_PP = 0x0,
+
+/* VP_REMAP field values */
+       HDMI_VP_REMAP_MASK = 0x3,
+       HDMI_VP_REMAP_YCC422_24bit = 0x2,
+       HDMI_VP_REMAP_YCC422_20bit = 0x1,
+       HDMI_VP_REMAP_YCC422_16bit = 0x0,
+
+/* FC_INVIDCONF field values */
+       HDMI_FC_INVIDCONF_HDCP_KEEPOUT_MASK = 0x80,
+       HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE = 0x80,
+       HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE = 0x00,
+       HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_MASK = 0x40,
+       HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH = 0x40,
+       HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW = 0x00,
+       HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_MASK = 0x20,
+       HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH = 0x20,
+       HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW = 0x00,
+       HDMI_FC_INVIDCONF_DE_IN_POLARITY_MASK = 0x10,
+       HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH = 0x10,
+       HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW = 0x00,
+       HDMI_FC_INVIDCONF_DVI_MODEZ_MASK = 0x8,
+       HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE = 0x8,
+       HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE = 0x0,
+       HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_MASK = 0x2,
+       HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH = 0x2,
+       HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW = 0x0,
+       HDMI_FC_INVIDCONF_IN_I_P_MASK = 0x1,
+       HDMI_FC_INVIDCONF_IN_I_P_INTERLACED = 0x1,
+       HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE = 0x0,
+
+/* FC_AUDICONF0 field values */
+       HDMI_FC_AUDICONF0_CC_OFFSET = 4,
+       HDMI_FC_AUDICONF0_CC_MASK = 0x70,
+       HDMI_FC_AUDICONF0_CT_OFFSET = 0,
+       HDMI_FC_AUDICONF0_CT_MASK = 0xF,
+
+/* FC_AUDICONF1 field values */
+       HDMI_FC_AUDICONF1_SS_OFFSET = 3,
+       HDMI_FC_AUDICONF1_SS_MASK = 0x18,
+       HDMI_FC_AUDICONF1_SF_OFFSET = 0,
+       HDMI_FC_AUDICONF1_SF_MASK = 0x7,
+
+/* FC_AUDICONF3 field values */
+       HDMI_FC_AUDICONF3_LFEPBL_OFFSET = 5,
+       HDMI_FC_AUDICONF3_LFEPBL_MASK = 0x60,
+       HDMI_FC_AUDICONF3_DM_INH_OFFSET = 4,
+       HDMI_FC_AUDICONF3_DM_INH_MASK = 0x10,
+       HDMI_FC_AUDICONF3_LSV_OFFSET = 0,
+       HDMI_FC_AUDICONF3_LSV_MASK = 0xF,
+
+/* FC_AUDSCHNLS0 field values */
+       HDMI_FC_AUDSCHNLS0_CGMSA_OFFSET = 4,
+       HDMI_FC_AUDSCHNLS0_CGMSA_MASK = 0x30,
+       HDMI_FC_AUDSCHNLS0_COPYRIGHT_OFFSET = 0,
+       HDMI_FC_AUDSCHNLS0_COPYRIGHT_MASK = 0x01,
+
+/* FC_AUDSCHNLS3-6 field values */
+       HDMI_FC_AUDSCHNLS3_OIEC_CH0_OFFSET = 0,
+       HDMI_FC_AUDSCHNLS3_OIEC_CH0_MASK = 0x0f,
+       HDMI_FC_AUDSCHNLS3_OIEC_CH1_OFFSET = 4,
+       HDMI_FC_AUDSCHNLS3_OIEC_CH1_MASK = 0xf0,
+       HDMI_FC_AUDSCHNLS4_OIEC_CH2_OFFSET = 0,
+       HDMI_FC_AUDSCHNLS4_OIEC_CH2_MASK = 0x0f,
+       HDMI_FC_AUDSCHNLS4_OIEC_CH3_OFFSET = 4,
+       HDMI_FC_AUDSCHNLS4_OIEC_CH3_MASK = 0xf0,
+
+       HDMI_FC_AUDSCHNLS5_OIEC_CH0_OFFSET = 0,
+       HDMI_FC_AUDSCHNLS5_OIEC_CH0_MASK = 0x0f,
+       HDMI_FC_AUDSCHNLS5_OIEC_CH1_OFFSET = 4,
+       HDMI_FC_AUDSCHNLS5_OIEC_CH1_MASK = 0xf0,
+       HDMI_FC_AUDSCHNLS6_OIEC_CH2_OFFSET = 0,
+       HDMI_FC_AUDSCHNLS6_OIEC_CH2_MASK = 0x0f,
+       HDMI_FC_AUDSCHNLS6_OIEC_CH3_OFFSET = 4,
+       HDMI_FC_AUDSCHNLS6_OIEC_CH3_MASK = 0xf0,
+
+/* HDMI_FC_AUDSCHNLS7 field values */
+       HDMI_FC_AUDSCHNLS7_ACCURACY_OFFSET = 4,
+       HDMI_FC_AUDSCHNLS7_ACCURACY_MASK = 0x30,
+
+/* HDMI_FC_AUDSCHNLS8 field values */
+       HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_MASK = 0xf0,
+       HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_OFFSET = 4,
+       HDMI_FC_AUDSCHNLS8_WORDLEGNTH_MASK = 0x0f,
+       HDMI_FC_AUDSCHNLS8_WORDLEGNTH_OFFSET = 0,
+
+/* FC_AUDSCONF field values */
+       HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_MASK = 0xF0,
+       HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_OFFSET = 4,
+       HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK = 0x1,
+       HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_OFFSET = 0,
+       HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT1 = 0x1,
+       HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT0 = 0x0,
+
+/* FC_STAT2 field values */
+       HDMI_FC_STAT2_OVERFLOW_MASK = 0x03,
+       HDMI_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
+       HDMI_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* FC_INT2 field values */
+       HDMI_FC_INT2_OVERFLOW_MASK = 0x03,
+       HDMI_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
+       HDMI_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* FC_MASK2 field values */
+       HDMI_FC_MASK2_OVERFLOW_MASK = 0x03,
+       HDMI_FC_MASK2_LOW_PRIORITY_OVERFLOW = 0x02,
+       HDMI_FC_MASK2_HIGH_PRIORITY_OVERFLOW = 0x01,
+
+/* FC_PRCONF field values */
+       HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK = 0xF0,
+       HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET = 4,
+       HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK = 0x0F,
+       HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET = 0,
+
+/* FC_AVICONF0-FC_AVICONF3 field values */
+       HDMI_FC_AVICONF0_PIX_FMT_MASK = 0x03,
+       HDMI_FC_AVICONF0_PIX_FMT_RGB = 0x00,
+       HDMI_FC_AVICONF0_PIX_FMT_YCBCR422 = 0x01,
+       HDMI_FC_AVICONF0_PIX_FMT_YCBCR444 = 0x02,
+       HDMI_FC_AVICONF0_ACTIVE_FMT_MASK = 0x40,
+       HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT = 0x40,
+       HDMI_FC_AVICONF0_ACTIVE_FMT_NO_INFO = 0x00,
+       HDMI_FC_AVICONF0_BAR_DATA_MASK = 0x0C,
+       HDMI_FC_AVICONF0_BAR_DATA_NO_DATA = 0x00,
+       HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR = 0x04,
+       HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR = 0x08,
+       HDMI_FC_AVICONF0_BAR_DATA_VERT_HORIZ_BAR = 0x0C,
+       HDMI_FC_AVICONF0_SCAN_INFO_MASK = 0x30,
+       HDMI_FC_AVICONF0_SCAN_INFO_OVERSCAN = 0x10,
+       HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN = 0x20,
+       HDMI_FC_AVICONF0_SCAN_INFO_NODATA = 0x00,
+
+       HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_MASK = 0x0F,
+       HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_USE_CODED = 0x08,
+       HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3 = 0x09,
+       HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9 = 0x0A,
+       HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_14_9 = 0x0B,
+       HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_MASK = 0x30,
+       HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_NO_DATA = 0x00,
+       HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3 = 0x10,
+       HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9 = 0x20,
+       HDMI_FC_AVICONF1_COLORIMETRY_MASK = 0xC0,
+       HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA = 0x00,
+       HDMI_FC_AVICONF1_COLORIMETRY_SMPTE = 0x40,
+       HDMI_FC_AVICONF1_COLORIMETRY_ITUR = 0x80,
+       HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO = 0xC0,
+
+       HDMI_FC_AVICONF2_SCALING_MASK = 0x03,
+       HDMI_FC_AVICONF2_SCALING_NONE = 0x00,
+       HDMI_FC_AVICONF2_SCALING_HORIZ = 0x01,
+       HDMI_FC_AVICONF2_SCALING_VERT = 0x02,
+       HDMI_FC_AVICONF2_SCALING_HORIZ_VERT = 0x03,
+       HDMI_FC_AVICONF2_RGB_QUANT_MASK = 0x0C,
+       HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT = 0x00,
+       HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE = 0x04,
+       HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE = 0x08,
+       HDMI_FC_AVICONF2_EXT_COLORIMETRY_MASK = 0x70,
+       HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601 = 0x00,
+       HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709 = 0x10,
+       HDMI_FC_AVICONF2_EXT_COLORIMETRY_SYCC601 = 0x20,
+       HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_YCC601 = 0x30,
+       HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_RGB = 0x40,
+       HDMI_FC_AVICONF2_IT_CONTENT_MASK = 0x80,
+       HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA = 0x00,
+       HDMI_FC_AVICONF2_IT_CONTENT_VALID = 0x80,
+
+       HDMI_FC_AVICONF3_IT_CONTENT_TYPE_MASK = 0x03,
+       HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS = 0x00,
+       HDMI_FC_AVICONF3_IT_CONTENT_TYPE_PHOTO = 0x01,
+       HDMI_FC_AVICONF3_IT_CONTENT_TYPE_CINEMA = 0x02,
+       HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GAME = 0x03,
+       HDMI_FC_AVICONF3_QUANT_RANGE_MASK = 0x0C,
+       HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED = 0x00,
+       HDMI_FC_AVICONF3_QUANT_RANGE_FULL = 0x04,
+
+/* FC_DBGFORCE field values */
+       HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10,
+       HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1,
+
+/* PHY_CONF0 field values */
+       HDMI_PHY_CONF0_PDZ_MASK = 0x80,
+       HDMI_PHY_CONF0_PDZ_OFFSET = 7,
+       HDMI_PHY_CONF0_ENTMDS_MASK = 0x40,
+       HDMI_PHY_CONF0_ENTMDS_OFFSET = 6,
+       HDMI_PHY_CONF0_SPARECTRL = 0x20,
+       HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10,
+       HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4,
+       HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8,
+       HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET = 3,
+       HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK = 0x4,
+       HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET = 2,
+       HDMI_PHY_CONF0_SELDATAENPOL_MASK = 0x2,
+       HDMI_PHY_CONF0_SELDATAENPOL_OFFSET = 1,
+       HDMI_PHY_CONF0_SELDIPIF_MASK = 0x1,
+       HDMI_PHY_CONF0_SELDIPIF_OFFSET = 0,
+
+/* PHY_TST0 field values */
+       HDMI_PHY_TST0_TSTCLR_MASK = 0x20,
+       HDMI_PHY_TST0_TSTCLR_OFFSET = 5,
+       HDMI_PHY_TST0_TSTEN_MASK = 0x10,
+       HDMI_PHY_TST0_TSTEN_OFFSET = 4,
+       HDMI_PHY_TST0_TSTCLK_MASK = 0x1,
+       HDMI_PHY_TST0_TSTCLK_OFFSET = 0,
+
+/* PHY_STAT0 field values */
+       HDMI_PHY_RX_SENSE3 = 0x80,
+       HDMI_PHY_RX_SENSE2 = 0x40,
+       HDMI_PHY_RX_SENSE1 = 0x20,
+       HDMI_PHY_RX_SENSE0 = 0x10,
+       HDMI_PHY_HPD = 0x02,
+       HDMI_PHY_TX_PHY_LOCK = 0x01,
+
+/* PHY_I2CM_SLAVE_ADDR field values */
+       HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2 = 0x69,
+       HDMI_PHY_I2CM_SLAVE_ADDR_HEAC_PHY = 0x49,
+
+/* PHY_I2CM_OPERATION_ADDR field values */
+       HDMI_PHY_I2CM_OPERATION_ADDR_WRITE = 0x10,
+       HDMI_PHY_I2CM_OPERATION_ADDR_READ = 0x1,
+
+/* HDMI_PHY_I2CM_INT_ADDR */
+       HDMI_PHY_I2CM_INT_ADDR_DONE_POL = 0x08,
+       HDMI_PHY_I2CM_INT_ADDR_DONE_MASK = 0x04,
+
+/* HDMI_PHY_I2CM_CTLINT_ADDR */
+       HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL = 0x80,
+       HDMI_PHY_I2CM_CTLINT_ADDR_NAC_MASK = 0x40,
+       HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL = 0x08,
+       HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_MASK = 0x04,
+
+/* AUD_CTS3 field values */
+       HDMI_AUD_CTS3_N_SHIFT_OFFSET = 5,
+       HDMI_AUD_CTS3_N_SHIFT_MASK = 0xe0,
+       HDMI_AUD_CTS3_N_SHIFT_1 = 0,
+       HDMI_AUD_CTS3_N_SHIFT_16 = 0x20,
+       HDMI_AUD_CTS3_N_SHIFT_32 = 0x40,
+       HDMI_AUD_CTS3_N_SHIFT_64 = 0x60,
+       HDMI_AUD_CTS3_N_SHIFT_128 = 0x80,
+       HDMI_AUD_CTS3_N_SHIFT_256 = 0xa0,
+       /* note that the CTS3 MANUAL bit has been removed
+          from our part. Can't set it, will read as 0. */
+       HDMI_AUD_CTS3_CTS_MANUAL = 0x10,
+       HDMI_AUD_CTS3_AUDCTS19_16_MASK = 0x0f,
+
+/* AHB_DMA_CONF0 field values */
+       HDMI_AHB_DMA_CONF0_SW_FIFO_RST_OFFSET = 7,
+       HDMI_AHB_DMA_CONF0_SW_FIFO_RST_MASK = 0x80,
+       HDMI_AHB_DMA_CONF0_HBR = 0x10,
+       HDMI_AHB_DMA_CONF0_EN_HLOCK_OFFSET = 3,
+       HDMI_AHB_DMA_CONF0_EN_HLOCK_MASK = 0x08,
+       HDMI_AHB_DMA_CONF0_INCR_TYPE_OFFSET = 1,
+       HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK = 0x06,
+       HDMI_AHB_DMA_CONF0_INCR4 = 0x0,
+       HDMI_AHB_DMA_CONF0_INCR8 = 0x2,
+       HDMI_AHB_DMA_CONF0_INCR16 = 0x4,
+       HDMI_AHB_DMA_CONF0_BURST_MODE = 0x1,
+
+/* HDMI_AHB_DMA_START field values */
+       HDMI_AHB_DMA_START_START_OFFSET = 0,
+       HDMI_AHB_DMA_START_START_MASK = 0x01,
+
+/* HDMI_AHB_DMA_STOP field values */
+       HDMI_AHB_DMA_STOP_STOP_OFFSET = 0,
+       HDMI_AHB_DMA_STOP_STOP_MASK = 0x01,
+
+/* AHB_DMA_STAT, AHB_DMA_INT, AHB_DMA_MASK, AHB_DMA_POL field values */
+       HDMI_AHB_DMA_DONE = 0x80,
+       HDMI_AHB_DMA_RETRY_SPLIT = 0x40,
+       HDMI_AHB_DMA_LOSTOWNERSHIP = 0x20,
+       HDMI_AHB_DMA_ERROR = 0x10,
+       HDMI_AHB_DMA_FIFO_THREMPTY = 0x04,
+       HDMI_AHB_DMA_FIFO_FULL = 0x02,
+       HDMI_AHB_DMA_FIFO_EMPTY = 0x01,
+
+/* AHB_DMA_BUFFSTAT, AHB_DMA_BUFFINT,AHB_DMA_BUFFMASK,AHB_DMA_BUFFPOL values */
+       HDMI_AHB_DMA_BUFFSTAT_FULL = 0x02,
+       HDMI_AHB_DMA_BUFFSTAT_EMPTY = 0x01,
+
+/* MC_CLKDIS field values */
+       HDMI_MC_CLKDIS_HDCPCLK_DISABLE = 0x40,
+       HDMI_MC_CLKDIS_CECCLK_DISABLE = 0x20,
+       HDMI_MC_CLKDIS_CSCCLK_DISABLE = 0x10,
+       HDMI_MC_CLKDIS_AUDCLK_DISABLE = 0x8,
+       HDMI_MC_CLKDIS_PREPCLK_DISABLE = 0x4,
+       HDMI_MC_CLKDIS_TMDSCLK_DISABLE = 0x2,
+       HDMI_MC_CLKDIS_PIXELCLK_DISABLE = 0x1,
+
+/* MC_SWRSTZ field values */
+       HDMI_MC_SWRSTZ_TMDSSWRST_REQ = 0x02,
+
+/* MC_FLOWCTRL field values */
+       HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_MASK = 0x1,
+       HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH = 0x1,
+       HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS = 0x0,
+
+/* MC_PHYRSTZ field values */
+       HDMI_MC_PHYRSTZ_ASSERT = 0x0,
+       HDMI_MC_PHYRSTZ_DEASSERT = 0x1,
+
+/* MC_HEACPHY_RST field values */
+       HDMI_MC_HEACPHY_RST_ASSERT = 0x1,
+       HDMI_MC_HEACPHY_RST_DEASSERT = 0x0,
+
+/* CSC_CFG field values */
+       HDMI_CSC_CFG_INTMODE_MASK = 0x30,
+       HDMI_CSC_CFG_INTMODE_OFFSET = 4,
+       HDMI_CSC_CFG_INTMODE_DISABLE = 0x00,
+       HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1 = 0x10,
+       HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA2 = 0x20,
+       HDMI_CSC_CFG_DECMODE_MASK = 0x3,
+       HDMI_CSC_CFG_DECMODE_OFFSET = 0,
+       HDMI_CSC_CFG_DECMODE_DISABLE = 0x0,
+       HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA1 = 0x1,
+       HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA2 = 0x2,
+       HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3 = 0x3,
+
+/* CSC_SCALE field values */
+       HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK = 0xF0,
+       HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP = 0x00,
+       HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP = 0x50,
+       HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP = 0x60,
+       HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP = 0x70,
+       HDMI_CSC_SCALE_CSCSCALE_MASK = 0x03,
+
+/* A_HDCPCFG0 field values */
+       HDMI_A_HDCPCFG0_ELVENA_MASK = 0x80,
+       HDMI_A_HDCPCFG0_ELVENA_ENABLE = 0x80,
+       HDMI_A_HDCPCFG0_ELVENA_DISABLE = 0x00,
+       HDMI_A_HDCPCFG0_I2CFASTMODE_MASK = 0x40,
+       HDMI_A_HDCPCFG0_I2CFASTMODE_ENABLE = 0x40,
+       HDMI_A_HDCPCFG0_I2CFASTMODE_DISABLE = 0x00,
+       HDMI_A_HDCPCFG0_BYPENCRYPTION_MASK = 0x20,
+       HDMI_A_HDCPCFG0_BYPENCRYPTION_ENABLE = 0x20,
+       HDMI_A_HDCPCFG0_BYPENCRYPTION_DISABLE = 0x00,
+       HDMI_A_HDCPCFG0_SYNCRICHECK_MASK = 0x10,
+       HDMI_A_HDCPCFG0_SYNCRICHECK_ENABLE = 0x10,
+       HDMI_A_HDCPCFG0_SYNCRICHECK_DISABLE = 0x00,
+       HDMI_A_HDCPCFG0_AVMUTE_MASK = 0x8,
+       HDMI_A_HDCPCFG0_AVMUTE_ENABLE = 0x8,
+       HDMI_A_HDCPCFG0_AVMUTE_DISABLE = 0x0,
+       HDMI_A_HDCPCFG0_RXDETECT_MASK = 0x4,
+       HDMI_A_HDCPCFG0_RXDETECT_ENABLE = 0x4,
+       HDMI_A_HDCPCFG0_RXDETECT_DISABLE = 0x0,
+       HDMI_A_HDCPCFG0_EN11FEATURE_MASK = 0x2,
+       HDMI_A_HDCPCFG0_EN11FEATURE_ENABLE = 0x2,
+       HDMI_A_HDCPCFG0_EN11FEATURE_DISABLE = 0x0,
+       HDMI_A_HDCPCFG0_HDMIDVI_MASK = 0x1,
+       HDMI_A_HDCPCFG0_HDMIDVI_HDMI = 0x1,
+       HDMI_A_HDCPCFG0_HDMIDVI_DVI = 0x0,
+
+/* A_HDCPCFG1 field values */
+       HDMI_A_HDCPCFG1_DISSHA1CHECK_MASK = 0x8,
+       HDMI_A_HDCPCFG1_DISSHA1CHECK_DISABLE = 0x8,
+       HDMI_A_HDCPCFG1_DISSHA1CHECK_ENABLE = 0x0,
+       HDMI_A_HDCPCFG1_PH2UPSHFTENC_MASK = 0x4,
+       HDMI_A_HDCPCFG1_PH2UPSHFTENC_ENABLE = 0x4,
+       HDMI_A_HDCPCFG1_PH2UPSHFTENC_DISABLE = 0x0,
+       HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK = 0x2,
+       HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE = 0x2,
+       HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_ENABLE = 0x0,
+       HDMI_A_HDCPCFG1_SWRESET_MASK = 0x1,
+       HDMI_A_HDCPCFG1_SWRESET_ASSERT = 0x0,
+
+/* A_VIDPOLCFG field values */
+       HDMI_A_VIDPOLCFG_UNENCRYPTCONF_MASK = 0x60,
+       HDMI_A_VIDPOLCFG_UNENCRYPTCONF_OFFSET = 5,
+       HDMI_A_VIDPOLCFG_DATAENPOL_MASK = 0x10,
+       HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH = 0x10,
+       HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW = 0x0,
+       HDMI_A_VIDPOLCFG_VSYNCPOL_MASK = 0x8,
+       HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_HIGH = 0x8,
+       HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_LOW = 0x0,
+       HDMI_A_VIDPOLCFG_HSYNCPOL_MASK = 0x2,
+       HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_HIGH = 0x2,
+       HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_LOW = 0x0,
+};
+#endif /* __IMX_HDMI_H__ */
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
new file mode 100644 (file)
index 0000000..4662e00
--- /dev/null
@@ -0,0 +1,616 @@
+/*
+ * i.MX drm driver - LVDS display bridge
+ *
+ * Copyright (C) 2012 Sascha Hauer, Pengutronix
+ *
+ * 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.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <drm/drmP.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <video/of_videomode.h>
+#include <linux/regmap.h>
+#include <linux/videodev2.h>
+
+#include "imx-drm.h"
+
+#define DRIVER_NAME "imx-ldb"
+
+#define LDB_CH0_MODE_EN_TO_DI0         (1 << 0)
+#define LDB_CH0_MODE_EN_TO_DI1         (3 << 0)
+#define LDB_CH0_MODE_EN_MASK           (3 << 0)
+#define LDB_CH1_MODE_EN_TO_DI0         (1 << 2)
+#define LDB_CH1_MODE_EN_TO_DI1         (3 << 2)
+#define LDB_CH1_MODE_EN_MASK           (3 << 2)
+#define LDB_SPLIT_MODE_EN              (1 << 4)
+#define LDB_DATA_WIDTH_CH0_24          (1 << 5)
+#define LDB_BIT_MAP_CH0_JEIDA          (1 << 6)
+#define LDB_DATA_WIDTH_CH1_24          (1 << 7)
+#define LDB_BIT_MAP_CH1_JEIDA          (1 << 8)
+#define LDB_DI0_VS_POL_ACT_LOW         (1 << 9)
+#define LDB_DI1_VS_POL_ACT_LOW         (1 << 10)
+#define LDB_BGREF_RMODE_INT            (1 << 15)
+
+#define con_to_imx_ldb_ch(x) container_of(x, struct imx_ldb_channel, connector)
+#define enc_to_imx_ldb_ch(x) container_of(x, struct imx_ldb_channel, encoder)
+
+struct imx_ldb;
+
+struct imx_ldb_channel {
+       struct imx_ldb *ldb;
+       struct drm_connector connector;
+       struct drm_encoder encoder;
+       struct device_node *child;
+       int chno;
+       void *edid;
+       int edid_len;
+       struct drm_display_mode mode;
+       int mode_valid;
+};
+
+struct bus_mux {
+       int reg;
+       int shift;
+       int mask;
+};
+
+struct imx_ldb {
+       struct regmap *regmap;
+       struct device *dev;
+       struct imx_ldb_channel channel[2];
+       struct clk *clk[2]; /* our own clock */
+       struct clk *clk_sel[4]; /* parent of display clock */
+       struct clk *clk_pll[2]; /* upstream clock we can adjust */
+       u32 ldb_ctrl;
+       const struct bus_mux *lvds_mux;
+};
+
+static enum drm_connector_status imx_ldb_connector_detect(
+               struct drm_connector *connector, bool force)
+{
+       return connector_status_connected;
+}
+
+static int imx_ldb_connector_get_modes(struct drm_connector *connector)
+{
+       struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector);
+       int num_modes = 0;
+
+       if (imx_ldb_ch->edid) {
+               drm_mode_connector_update_edid_property(connector,
+                                                       imx_ldb_ch->edid);
+               num_modes = drm_add_edid_modes(connector, imx_ldb_ch->edid);
+       }
+
+       if (imx_ldb_ch->mode_valid) {
+               struct drm_display_mode *mode;
+
+               mode = drm_mode_create(connector->dev);
+               if (!mode)
+                       return -EINVAL;
+               drm_mode_copy(mode, &imx_ldb_ch->mode);
+               mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+               drm_mode_probed_add(connector, mode);
+               num_modes++;
+       }
+
+       return num_modes;
+}
+
+static struct drm_encoder *imx_ldb_connector_best_encoder(
+               struct drm_connector *connector)
+{
+       struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector);
+
+       return &imx_ldb_ch->encoder;
+}
+
+static void imx_ldb_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+}
+
+static bool imx_ldb_encoder_mode_fixup(struct drm_encoder *encoder,
+                          const struct drm_display_mode *mode,
+                          struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno,
+               unsigned long serial_clk, unsigned long di_clk)
+{
+       int ret;
+
+       dev_dbg(ldb->dev, "%s: now: %ld want: %ld\n", __func__,
+                       clk_get_rate(ldb->clk_pll[chno]), serial_clk);
+       clk_set_rate(ldb->clk_pll[chno], serial_clk);
+
+       dev_dbg(ldb->dev, "%s after: %ld\n", __func__,
+                       clk_get_rate(ldb->clk_pll[chno]));
+
+       dev_dbg(ldb->dev, "%s: now: %ld want: %ld\n", __func__,
+                       clk_get_rate(ldb->clk[chno]),
+                       (long int)di_clk);
+       clk_set_rate(ldb->clk[chno], di_clk);
+
+       dev_dbg(ldb->dev, "%s after: %ld\n", __func__,
+                       clk_get_rate(ldb->clk[chno]));
+
+       /* set display clock mux to LDB input clock */
+       ret = clk_set_parent(ldb->clk_sel[mux], ldb->clk[chno]);
+       if (ret)
+               dev_err(ldb->dev,
+                       "unable to set di%d parent clock to ldb_di%d\n", mux,
+                       chno);
+}
+
+static void imx_ldb_encoder_prepare(struct drm_encoder *encoder)
+{
+       struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
+       struct imx_ldb *ldb = imx_ldb_ch->ldb;
+       struct drm_display_mode *mode = &encoder->crtc->mode;
+       u32 pixel_fmt;
+       unsigned long serial_clk;
+       unsigned long di_clk = mode->clock * 1000;
+       int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder);
+
+       if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) {
+               /* dual channel LVDS mode */
+               serial_clk = 3500UL * mode->clock;
+               imx_ldb_set_clock(ldb, mux, 0, serial_clk, di_clk);
+               imx_ldb_set_clock(ldb, mux, 1, serial_clk, di_clk);
+       } else {
+               serial_clk = 7000UL * mode->clock;
+               imx_ldb_set_clock(ldb, mux, imx_ldb_ch->chno, serial_clk,
+                               di_clk);
+       }
+
+       switch (imx_ldb_ch->chno) {
+       case 0:
+               pixel_fmt = (ldb->ldb_ctrl & LDB_DATA_WIDTH_CH0_24) ?
+                       V4L2_PIX_FMT_RGB24 : V4L2_PIX_FMT_BGR666;
+               break;
+       case 1:
+               pixel_fmt = (ldb->ldb_ctrl & LDB_DATA_WIDTH_CH1_24) ?
+                       V4L2_PIX_FMT_RGB24 : V4L2_PIX_FMT_BGR666;
+               break;
+       default:
+               dev_err(ldb->dev, "unable to config di%d panel format\n",
+                       imx_ldb_ch->chno);
+               pixel_fmt = V4L2_PIX_FMT_RGB24;
+       }
+
+       imx_drm_panel_format(encoder, pixel_fmt);
+}
+
+static void imx_ldb_encoder_commit(struct drm_encoder *encoder)
+{
+       struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
+       struct imx_ldb *ldb = imx_ldb_ch->ldb;
+       int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
+       int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder);
+
+       if (dual) {
+               clk_prepare_enable(ldb->clk[0]);
+               clk_prepare_enable(ldb->clk[1]);
+       }
+
+       if (imx_ldb_ch == &ldb->channel[0] || dual) {
+               ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK;
+               if (mux == 0 || ldb->lvds_mux)
+                       ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI0;
+               else if (mux == 1)
+                       ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI1;
+       }
+       if (imx_ldb_ch == &ldb->channel[1] || dual) {
+               ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK;
+               if (mux == 1 || ldb->lvds_mux)
+                       ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI1;
+               else if (mux == 0)
+                       ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI0;
+       }
+
+       if (ldb->lvds_mux) {
+               const struct bus_mux *lvds_mux = NULL;
+
+               if (imx_ldb_ch == &ldb->channel[0])
+                       lvds_mux = &ldb->lvds_mux[0];
+               else if (imx_ldb_ch == &ldb->channel[1])
+                       lvds_mux = &ldb->lvds_mux[1];
+
+               regmap_update_bits(ldb->regmap, lvds_mux->reg, lvds_mux->mask,
+                                  mux << lvds_mux->shift);
+       }
+
+       regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl);
+}
+
+static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder,
+                        struct drm_display_mode *mode,
+                        struct drm_display_mode *adjusted_mode)
+{
+       struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
+       struct imx_ldb *ldb = imx_ldb_ch->ldb;
+       int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
+
+       if (mode->clock > 170000) {
+               dev_warn(ldb->dev,
+                        "%s: mode exceeds 170 MHz pixel clock\n", __func__);
+       }
+       if (mode->clock > 85000 && !dual) {
+               dev_warn(ldb->dev,
+                        "%s: mode exceeds 85 MHz pixel clock\n", __func__);
+       }
+
+       /* FIXME - assumes straight connections DI0 --> CH0, DI1 --> CH1 */
+       if (imx_ldb_ch == &ldb->channel[0]) {
+               if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+                       ldb->ldb_ctrl |= LDB_DI0_VS_POL_ACT_LOW;
+               else if (mode->flags & DRM_MODE_FLAG_PVSYNC)
+                       ldb->ldb_ctrl &= ~LDB_DI0_VS_POL_ACT_LOW;
+       }
+       if (imx_ldb_ch == &ldb->channel[1]) {
+               if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+                       ldb->ldb_ctrl |= LDB_DI1_VS_POL_ACT_LOW;
+               else if (mode->flags & DRM_MODE_FLAG_PVSYNC)
+                       ldb->ldb_ctrl &= ~LDB_DI1_VS_POL_ACT_LOW;
+       }
+}
+
+static void imx_ldb_encoder_disable(struct drm_encoder *encoder)
+{
+       struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
+       struct imx_ldb *ldb = imx_ldb_ch->ldb;
+
+       /*
+        * imx_ldb_encoder_disable is called by
+        * drm_helper_disable_unused_functions without
+        * the encoder being enabled before.
+        */
+       if (imx_ldb_ch == &ldb->channel[0] &&
+           (ldb->ldb_ctrl & LDB_CH0_MODE_EN_MASK) == 0)
+               return;
+       else if (imx_ldb_ch == &ldb->channel[1] &&
+                (ldb->ldb_ctrl & LDB_CH1_MODE_EN_MASK) == 0)
+               return;
+
+       if (imx_ldb_ch == &ldb->channel[0])
+               ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK;
+       else if (imx_ldb_ch == &ldb->channel[1])
+               ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK;
+
+       regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl);
+
+       if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) {
+               clk_disable_unprepare(ldb->clk[0]);
+               clk_disable_unprepare(ldb->clk[1]);
+       }
+}
+
+static struct drm_connector_funcs imx_ldb_connector_funcs = {
+       .dpms = drm_helper_connector_dpms,
+       .fill_modes = drm_helper_probe_single_connector_modes,
+       .detect = imx_ldb_connector_detect,
+       .destroy = imx_drm_connector_destroy,
+};
+
+static struct drm_connector_helper_funcs imx_ldb_connector_helper_funcs = {
+       .get_modes = imx_ldb_connector_get_modes,
+       .best_encoder = imx_ldb_connector_best_encoder,
+};
+
+static struct drm_encoder_funcs imx_ldb_encoder_funcs = {
+       .destroy = imx_drm_encoder_destroy,
+};
+
+static struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = {
+       .dpms = imx_ldb_encoder_dpms,
+       .mode_fixup = imx_ldb_encoder_mode_fixup,
+       .prepare = imx_ldb_encoder_prepare,
+       .commit = imx_ldb_encoder_commit,
+       .mode_set = imx_ldb_encoder_mode_set,
+       .disable = imx_ldb_encoder_disable,
+};
+
+static int imx_ldb_get_clk(struct imx_ldb *ldb, int chno)
+{
+       char clkname[16];
+
+       snprintf(clkname, sizeof(clkname), "di%d", chno);
+       ldb->clk[chno] = devm_clk_get(ldb->dev, clkname);
+       if (IS_ERR(ldb->clk[chno]))
+               return PTR_ERR(ldb->clk[chno]);
+
+       snprintf(clkname, sizeof(clkname), "di%d_pll", chno);
+       ldb->clk_pll[chno] = devm_clk_get(ldb->dev, clkname);
+
+       return PTR_ERR_OR_ZERO(ldb->clk_pll[chno]);
+}
+
+static int imx_ldb_register(struct drm_device *drm,
+       struct imx_ldb_channel *imx_ldb_ch)
+{
+       struct imx_ldb *ldb = imx_ldb_ch->ldb;
+       int ret;
+
+       ret = imx_drm_encoder_parse_of(drm, &imx_ldb_ch->encoder,
+                                      imx_ldb_ch->child);
+       if (ret)
+               return ret;
+
+       ret = imx_ldb_get_clk(ldb, imx_ldb_ch->chno);
+       if (ret)
+               return ret;
+
+       if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) {
+               ret = imx_ldb_get_clk(ldb, 1);
+               if (ret)
+                       return ret;
+       }
+
+       drm_encoder_helper_add(&imx_ldb_ch->encoder,
+                       &imx_ldb_encoder_helper_funcs);
+       drm_encoder_init(drm, &imx_ldb_ch->encoder, &imx_ldb_encoder_funcs,
+                        DRM_MODE_ENCODER_LVDS);
+
+       drm_connector_helper_add(&imx_ldb_ch->connector,
+                       &imx_ldb_connector_helper_funcs);
+       drm_connector_init(drm, &imx_ldb_ch->connector,
+                          &imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
+
+       drm_mode_connector_attach_encoder(&imx_ldb_ch->connector,
+                       &imx_ldb_ch->encoder);
+
+       return 0;
+}
+
+enum {
+       LVDS_BIT_MAP_SPWG,
+       LVDS_BIT_MAP_JEIDA
+};
+
+static const char * const imx_ldb_bit_mappings[] = {
+       [LVDS_BIT_MAP_SPWG]  = "spwg",
+       [LVDS_BIT_MAP_JEIDA] = "jeida",
+};
+
+static const int of_get_data_mapping(struct device_node *np)
+{
+       const char *bm;
+       int ret, i;
+
+       ret = of_property_read_string(np, "fsl,data-mapping", &bm);
+       if (ret < 0)
+               return ret;
+
+       for (i = 0; i < ARRAY_SIZE(imx_ldb_bit_mappings); i++)
+               if (!strcasecmp(bm, imx_ldb_bit_mappings[i]))
+                       return i;
+
+       return -EINVAL;
+}
+
+static struct bus_mux imx6q_lvds_mux[2] = {
+       {
+               .reg = IOMUXC_GPR3,
+               .shift = 6,
+               .mask = IMX6Q_GPR3_LVDS0_MUX_CTL_MASK,
+       }, {
+               .reg = IOMUXC_GPR3,
+               .shift = 8,
+               .mask = IMX6Q_GPR3_LVDS1_MUX_CTL_MASK,
+       }
+};
+
+/*
+ * For a device declaring compatible = "fsl,imx6q-ldb", "fsl,imx53-ldb",
+ * of_match_device will walk through this list and take the first entry
+ * matching any of its compatible values. Therefore, the more generic
+ * entries (in this case fsl,imx53-ldb) need to be ordered last.
+ */
+static const struct of_device_id imx_ldb_dt_ids[] = {
+       { .compatible = "fsl,imx6q-ldb", .data = imx6q_lvds_mux, },
+       { .compatible = "fsl,imx53-ldb", .data = NULL, },
+       { }
+};
+MODULE_DEVICE_TABLE(of, imx_ldb_dt_ids);
+
+static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
+{
+       struct drm_device *drm = data;
+       struct device_node *np = dev->of_node;
+       const struct of_device_id *of_id =
+                       of_match_device(imx_ldb_dt_ids, dev);
+       struct device_node *child;
+       const u8 *edidp;
+       struct imx_ldb *imx_ldb;
+       int datawidth;
+       int mapping;
+       int dual;
+       int ret;
+       int i;
+
+       imx_ldb = devm_kzalloc(dev, sizeof(*imx_ldb), GFP_KERNEL);
+       if (!imx_ldb)
+               return -ENOMEM;
+
+       imx_ldb->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
+       if (IS_ERR(imx_ldb->regmap)) {
+               dev_err(dev, "failed to get parent regmap\n");
+               return PTR_ERR(imx_ldb->regmap);
+       }
+
+       imx_ldb->dev = dev;
+
+       if (of_id)
+               imx_ldb->lvds_mux = of_id->data;
+
+       dual = of_property_read_bool(np, "fsl,dual-channel");
+       if (dual)
+               imx_ldb->ldb_ctrl |= LDB_SPLIT_MODE_EN;
+
+       /*
+        * There are three different possible clock mux configurations:
+        * i.MX53:  ipu1_di0_sel, ipu1_di1_sel
+        * i.MX6q:  ipu1_di0_sel, ipu1_di1_sel, ipu2_di0_sel, ipu2_di1_sel
+        * i.MX6dl: ipu1_di0_sel, ipu1_di1_sel, lcdif_sel
+        * Map them all to di0_sel...di3_sel.
+        */
+       for (i = 0; i < 4; i++) {
+               char clkname[16];
+
+               sprintf(clkname, "di%d_sel", i);
+               imx_ldb->clk_sel[i] = devm_clk_get(imx_ldb->dev, clkname);
+               if (IS_ERR(imx_ldb->clk_sel[i])) {
+                       ret = PTR_ERR(imx_ldb->clk_sel[i]);
+                       imx_ldb->clk_sel[i] = NULL;
+                       break;
+               }
+       }
+       if (i == 0)
+               return ret;
+
+       for_each_child_of_node(np, child) {
+               struct imx_ldb_channel *channel;
+
+               ret = of_property_read_u32(child, "reg", &i);
+               if (ret || i < 0 || i > 1)
+                       return -EINVAL;
+
+               if (dual && i > 0) {
+                       dev_warn(dev, "dual-channel mode, ignoring second output\n");
+                       continue;
+               }
+
+               if (!of_device_is_available(child))
+                       continue;
+
+               channel = &imx_ldb->channel[i];
+               channel->ldb = imx_ldb;
+               channel->chno = i;
+               channel->child = child;
+
+               edidp = of_get_property(child, "edid", &channel->edid_len);
+               if (edidp) {
+                       channel->edid = kmemdup(edidp, channel->edid_len,
+                                               GFP_KERNEL);
+               } else {
+                       ret = of_get_drm_display_mode(child, &channel->mode, 0);
+                       if (!ret)
+                               channel->mode_valid = 1;
+               }
+
+               ret = of_property_read_u32(child, "fsl,data-width", &datawidth);
+               if (ret)
+                       datawidth = 0;
+               else if (datawidth != 18 && datawidth != 24)
+                       return -EINVAL;
+
+               mapping = of_get_data_mapping(child);
+               switch (mapping) {
+               case LVDS_BIT_MAP_SPWG:
+                       if (datawidth == 24) {
+                               if (i == 0 || dual)
+                                       imx_ldb->ldb_ctrl |=
+                                               LDB_DATA_WIDTH_CH0_24;
+                               if (i == 1 || dual)
+                                       imx_ldb->ldb_ctrl |=
+                                               LDB_DATA_WIDTH_CH1_24;
+                       }
+                       break;
+               case LVDS_BIT_MAP_JEIDA:
+                       if (datawidth == 18) {
+                               dev_err(dev, "JEIDA standard only supported in 24 bit\n");
+                               return -EINVAL;
+                       }
+                       if (i == 0 || dual)
+                               imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 |
+                                       LDB_BIT_MAP_CH0_JEIDA;
+                       if (i == 1 || dual)
+                               imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 |
+                                       LDB_BIT_MAP_CH1_JEIDA;
+                       break;
+               default:
+                       dev_err(dev, "data mapping not specified or invalid\n");
+                       return -EINVAL;
+               }
+
+               ret = imx_ldb_register(drm, channel);
+               if (ret)
+                       return ret;
+       }
+
+       dev_set_drvdata(dev, imx_ldb);
+
+       return 0;
+}
+
+static void imx_ldb_unbind(struct device *dev, struct device *master,
+       void *data)
+{
+       struct imx_ldb *imx_ldb = dev_get_drvdata(dev);
+       int i;
+
+       for (i = 0; i < 2; i++) {
+               struct imx_ldb_channel *channel = &imx_ldb->channel[i];
+
+               if (!channel->connector.funcs)
+                       continue;
+
+               channel->connector.funcs->destroy(&channel->connector);
+               channel->encoder.funcs->destroy(&channel->encoder);
+       }
+}
+
+static const struct component_ops imx_ldb_ops = {
+       .bind   = imx_ldb_bind,
+       .unbind = imx_ldb_unbind,
+};
+
+static int imx_ldb_probe(struct platform_device *pdev)
+{
+       return component_add(&pdev->dev, &imx_ldb_ops);
+}
+
+static int imx_ldb_remove(struct platform_device *pdev)
+{
+       component_del(&pdev->dev, &imx_ldb_ops);
+       return 0;
+}
+
+static struct platform_driver imx_ldb_driver = {
+       .probe          = imx_ldb_probe,
+       .remove         = imx_ldb_remove,
+       .driver         = {
+               .of_match_table = imx_ldb_dt_ids,
+               .name   = DRIVER_NAME,
+               .owner  = THIS_MODULE,
+       },
+};
+
+module_platform_driver(imx_ldb_driver);
+
+MODULE_DESCRIPTION("i.MX LVDS driver");
+MODULE_AUTHOR("Sascha Hauer, Pengutronix");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
new file mode 100644 (file)
index 0000000..42c651b
--- /dev/null
@@ -0,0 +1,736 @@
+/*
+ * i.MX drm driver - Television Encoder (TVEv2)
+ *
+ * Copyright (C) 2013 Philipp Zabel, Pengutronix
+ *
+ * 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.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/component.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spinlock.h>
+#include <linux/videodev2.h>
+#include <drm/drmP.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <video/imx-ipu-v3.h>
+
+#include "imx-drm.h"
+
+#define TVE_COM_CONF_REG       0x00
+#define TVE_TVDAC0_CONT_REG    0x28
+#define TVE_TVDAC1_CONT_REG    0x2c
+#define TVE_TVDAC2_CONT_REG    0x30
+#define TVE_CD_CONT_REG                0x34
+#define TVE_INT_CONT_REG       0x64
+#define TVE_STAT_REG           0x68
+#define TVE_TST_MODE_REG       0x6c
+#define TVE_MV_CONT_REG                0xdc
+
+/* TVE_COM_CONF_REG */
+#define TVE_SYNC_CH_2_EN       BIT(22)
+#define TVE_SYNC_CH_1_EN       BIT(21)
+#define TVE_SYNC_CH_0_EN       BIT(20)
+#define TVE_TV_OUT_MODE_MASK   (0x7 << 12)
+#define TVE_TV_OUT_DISABLE     (0x0 << 12)
+#define TVE_TV_OUT_CVBS_0      (0x1 << 12)
+#define TVE_TV_OUT_CVBS_2      (0x2 << 12)
+#define TVE_TV_OUT_CVBS_0_2    (0x3 << 12)
+#define TVE_TV_OUT_SVIDEO_0_1  (0x4 << 12)
+#define TVE_TV_OUT_SVIDEO_0_1_CVBS2_2  (0x5 << 12)
+#define TVE_TV_OUT_YPBPR       (0x6 << 12)
+#define TVE_TV_OUT_RGB         (0x7 << 12)
+#define TVE_TV_STAND_MASK      (0xf << 8)
+#define TVE_TV_STAND_HD_1080P30        (0xc << 8)
+#define TVE_P2I_CONV_EN                BIT(7)
+#define TVE_INP_VIDEO_FORM     BIT(6)
+#define TVE_INP_YCBCR_422      (0x0 << 6)
+#define TVE_INP_YCBCR_444      (0x1 << 6)
+#define TVE_DATA_SOURCE_MASK   (0x3 << 4)
+#define TVE_DATA_SOURCE_BUS1   (0x0 << 4)
+#define TVE_DATA_SOURCE_BUS2   (0x1 << 4)
+#define TVE_DATA_SOURCE_EXT    (0x2 << 4)
+#define TVE_DATA_SOURCE_TESTGEN        (0x3 << 4)
+#define TVE_IPU_CLK_EN_OFS     3
+#define TVE_IPU_CLK_EN         BIT(3)
+#define TVE_DAC_SAMP_RATE_OFS  1
+#define TVE_DAC_SAMP_RATE_WIDTH        2
+#define TVE_DAC_SAMP_RATE_MASK (0x3 << 1)
+#define TVE_DAC_FULL_RATE      (0x0 << 1)
+#define TVE_DAC_DIV2_RATE      (0x1 << 1)
+#define TVE_DAC_DIV4_RATE      (0x2 << 1)
+#define TVE_EN                 BIT(0)
+
+/* TVE_TVDACx_CONT_REG */
+#define TVE_TVDAC_GAIN_MASK    (0x3f << 0)
+
+/* TVE_CD_CONT_REG */
+#define TVE_CD_CH_2_SM_EN      BIT(22)
+#define TVE_CD_CH_1_SM_EN      BIT(21)
+#define TVE_CD_CH_0_SM_EN      BIT(20)
+#define TVE_CD_CH_2_LM_EN      BIT(18)
+#define TVE_CD_CH_1_LM_EN      BIT(17)
+#define TVE_CD_CH_0_LM_EN      BIT(16)
+#define TVE_CD_CH_2_REF_LVL    BIT(10)
+#define TVE_CD_CH_1_REF_LVL    BIT(9)
+#define TVE_CD_CH_0_REF_LVL    BIT(8)
+#define TVE_CD_EN              BIT(0)
+
+/* TVE_INT_CONT_REG */
+#define TVE_FRAME_END_IEN      BIT(13)
+#define TVE_CD_MON_END_IEN     BIT(2)
+#define TVE_CD_SM_IEN          BIT(1)
+#define TVE_CD_LM_IEN          BIT(0)
+
+/* TVE_TST_MODE_REG */
+#define TVE_TVDAC_TEST_MODE_MASK       (0x7 << 0)
+
+#define con_to_tve(x) container_of(x, struct imx_tve, connector)
+#define enc_to_tve(x) container_of(x, struct imx_tve, encoder)
+
+enum {
+       TVE_MODE_TVOUT,
+       TVE_MODE_VGA,
+};
+
+struct imx_tve {
+       struct drm_connector connector;
+       struct drm_encoder encoder;
+       struct device *dev;
+       spinlock_t lock;        /* register lock */
+       bool enabled;
+       int mode;
+
+       struct regmap *regmap;
+       struct regulator *dac_reg;
+       struct i2c_adapter *ddc;
+       struct clk *clk;
+       struct clk *di_sel_clk;
+       struct clk_hw clk_hw_di;
+       struct clk *di_clk;
+       int vsync_pin;
+       int hsync_pin;
+};
+
+static void tve_lock(void *__tve)
+__acquires(&tve->lock)
+{
+       struct imx_tve *tve = __tve;
+
+       spin_lock(&tve->lock);
+}
+
+static void tve_unlock(void *__tve)
+__releases(&tve->lock)
+{
+       struct imx_tve *tve = __tve;
+
+       spin_unlock(&tve->lock);
+}
+
+static void tve_enable(struct imx_tve *tve)
+{
+       int ret;
+
+       if (!tve->enabled) {
+               tve->enabled = true;
+               clk_prepare_enable(tve->clk);
+               ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG,
+                                        TVE_IPU_CLK_EN | TVE_EN,
+                                        TVE_IPU_CLK_EN | TVE_EN);
+       }
+
+       /* clear interrupt status register */
+       regmap_write(tve->regmap, TVE_STAT_REG, 0xffffffff);
+
+       /* cable detection irq disabled in VGA mode, enabled in TVOUT mode */
+       if (tve->mode == TVE_MODE_VGA)
+               regmap_write(tve->regmap, TVE_INT_CONT_REG, 0);
+       else
+               regmap_write(tve->regmap, TVE_INT_CONT_REG,
+                            TVE_CD_SM_IEN |
+                            TVE_CD_LM_IEN |
+                            TVE_CD_MON_END_IEN);
+}
+
+static void tve_disable(struct imx_tve *tve)
+{
+       int ret;
+
+       if (tve->enabled) {
+               tve->enabled = false;
+               ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG,
+                                        TVE_IPU_CLK_EN | TVE_EN, 0);
+               clk_disable_unprepare(tve->clk);
+       }
+}
+
+static int tve_setup_tvout(struct imx_tve *tve)
+{
+       return -ENOTSUPP;
+}
+
+static int tve_setup_vga(struct imx_tve *tve)
+{
+       unsigned int mask;
+       unsigned int val;
+       int ret;
+
+       /* set gain to (1 + 10/128) to provide 0.7V peak-to-peak amplitude */
+       ret = regmap_update_bits(tve->regmap, TVE_TVDAC0_CONT_REG,
+                                TVE_TVDAC_GAIN_MASK, 0x0a);
+       ret = regmap_update_bits(tve->regmap, TVE_TVDAC1_CONT_REG,
+                                TVE_TVDAC_GAIN_MASK, 0x0a);
+       ret = regmap_update_bits(tve->regmap, TVE_TVDAC2_CONT_REG,
+                                TVE_TVDAC_GAIN_MASK, 0x0a);
+
+       /* set configuration register */
+       mask = TVE_DATA_SOURCE_MASK | TVE_INP_VIDEO_FORM;
+       val  = TVE_DATA_SOURCE_BUS2 | TVE_INP_YCBCR_444;
+       mask |= TVE_TV_STAND_MASK       | TVE_P2I_CONV_EN;
+       val  |= TVE_TV_STAND_HD_1080P30 | 0;
+       mask |= TVE_TV_OUT_MODE_MASK | TVE_SYNC_CH_0_EN;
+       val  |= TVE_TV_OUT_RGB       | TVE_SYNC_CH_0_EN;
+       ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, mask, val);
+       if (ret < 0) {
+               dev_err(tve->dev, "failed to set configuration: %d\n", ret);
+               return ret;
+       }
+
+       /* set test mode (as documented) */
+       ret = regmap_update_bits(tve->regmap, TVE_TST_MODE_REG,
+                                TVE_TVDAC_TEST_MODE_MASK, 1);
+
+       return 0;
+}
+
+static enum drm_connector_status imx_tve_connector_detect(
+                               struct drm_connector *connector, bool force)
+{
+       return connector_status_connected;
+}
+
+static int imx_tve_connector_get_modes(struct drm_connector *connector)
+{
+       struct imx_tve *tve = con_to_tve(connector);
+       struct edid *edid;
+       int ret = 0;
+
+       if (!tve->ddc)
+               return 0;
+
+       edid = drm_get_edid(connector, tve->ddc);
+       if (edid) {
+               drm_mode_connector_update_edid_property(connector, edid);
+               ret = drm_add_edid_modes(connector, edid);
+               kfree(edid);
+       }
+
+       return ret;
+}
+
+static int imx_tve_connector_mode_valid(struct drm_connector *connector,
+                                       struct drm_display_mode *mode)
+{
+       struct imx_tve *tve = con_to_tve(connector);
+       unsigned long rate;
+
+       /* pixel clock with 2x oversampling */
+       rate = clk_round_rate(tve->clk, 2000UL * mode->clock) / 2000;
+       if (rate == mode->clock)
+               return MODE_OK;
+
+       /* pixel clock without oversampling */
+       rate = clk_round_rate(tve->clk, 1000UL * mode->clock) / 1000;
+       if (rate == mode->clock)
+               return MODE_OK;
+
+       dev_warn(tve->dev, "ignoring mode %dx%d\n",
+                mode->hdisplay, mode->vdisplay);
+
+       return MODE_BAD;
+}
+
+static struct drm_encoder *imx_tve_connector_best_encoder(
+               struct drm_connector *connector)
+{
+       struct imx_tve *tve = con_to_tve(connector);
+
+       return &tve->encoder;
+}
+
+static void imx_tve_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+       struct imx_tve *tve = enc_to_tve(encoder);
+       int ret;
+
+       ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG,
+                                TVE_TV_OUT_MODE_MASK, TVE_TV_OUT_DISABLE);
+       if (ret < 0)
+               dev_err(tve->dev, "failed to disable TVOUT: %d\n", ret);
+}
+
+static bool imx_tve_encoder_mode_fixup(struct drm_encoder *encoder,
+                                      const struct drm_display_mode *mode,
+                                      struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+static void imx_tve_encoder_prepare(struct drm_encoder *encoder)
+{
+       struct imx_tve *tve = enc_to_tve(encoder);
+
+       tve_disable(tve);
+
+       switch (tve->mode) {
+       case TVE_MODE_VGA:
+               imx_drm_panel_format_pins(encoder, IPU_PIX_FMT_GBR24,
+                               tve->hsync_pin, tve->vsync_pin);
+               break;
+       case TVE_MODE_TVOUT:
+               imx_drm_panel_format(encoder, V4L2_PIX_FMT_YUV444);
+               break;
+       }
+}
+
+static void imx_tve_encoder_mode_set(struct drm_encoder *encoder,
+                                    struct drm_display_mode *mode,
+                                    struct drm_display_mode *adjusted_mode)
+{
+       struct imx_tve *tve = enc_to_tve(encoder);
+       unsigned long rounded_rate;
+       unsigned long rate;
+       int div = 1;
+       int ret;
+
+       /*
+        * FIXME
+        * we should try 4k * mode->clock first,
+        * and enable 4x oversampling for lower resolutions
+        */
+       rate = 2000UL * mode->clock;
+       clk_set_rate(tve->clk, rate);
+       rounded_rate = clk_get_rate(tve->clk);
+       if (rounded_rate >= rate)
+               div = 2;
+       clk_set_rate(tve->di_clk, rounded_rate / div);
+
+       ret = clk_set_parent(tve->di_sel_clk, tve->di_clk);
+       if (ret < 0) {
+               dev_err(tve->dev, "failed to set di_sel parent to tve_di: %d\n",
+                       ret);
+       }
+
+       if (tve->mode == TVE_MODE_VGA)
+               tve_setup_vga(tve);
+       else
+               tve_setup_tvout(tve);
+}
+
+static void imx_tve_encoder_commit(struct drm_encoder *encoder)
+{
+       struct imx_tve *tve = enc_to_tve(encoder);
+
+       tve_enable(tve);
+}
+
+static void imx_tve_encoder_disable(struct drm_encoder *encoder)
+{
+       struct imx_tve *tve = enc_to_tve(encoder);
+
+       tve_disable(tve);
+}
+
+static struct drm_connector_funcs imx_tve_connector_funcs = {
+       .dpms = drm_helper_connector_dpms,
+       .fill_modes = drm_helper_probe_single_connector_modes,
+       .detect = imx_tve_connector_detect,
+       .destroy = imx_drm_connector_destroy,
+};
+
+static struct drm_connector_helper_funcs imx_tve_connector_helper_funcs = {
+       .get_modes = imx_tve_connector_get_modes,
+       .best_encoder = imx_tve_connector_best_encoder,
+       .mode_valid = imx_tve_connector_mode_valid,
+};
+
+static struct drm_encoder_funcs imx_tve_encoder_funcs = {
+       .destroy = imx_drm_encoder_destroy,
+};
+
+static struct drm_encoder_helper_funcs imx_tve_encoder_helper_funcs = {
+       .dpms = imx_tve_encoder_dpms,
+       .mode_fixup = imx_tve_encoder_mode_fixup,
+       .prepare = imx_tve_encoder_prepare,
+       .mode_set = imx_tve_encoder_mode_set,
+       .commit = imx_tve_encoder_commit,
+       .disable = imx_tve_encoder_disable,
+};
+
+static irqreturn_t imx_tve_irq_handler(int irq, void *data)
+{
+       struct imx_tve *tve = data;
+       unsigned int val;
+
+       regmap_read(tve->regmap, TVE_STAT_REG, &val);
+
+       /* clear interrupt status register */
+       regmap_write(tve->regmap, TVE_STAT_REG, 0xffffffff);
+
+       return IRQ_HANDLED;
+}
+
+static unsigned long clk_tve_di_recalc_rate(struct clk_hw *hw,
+                                           unsigned long parent_rate)
+{
+       struct imx_tve *tve = container_of(hw, struct imx_tve, clk_hw_di);
+       unsigned int val;
+       int ret;
+
+       ret = regmap_read(tve->regmap, TVE_COM_CONF_REG, &val);
+       if (ret < 0)
+               return 0;
+
+       switch (val & TVE_DAC_SAMP_RATE_MASK) {
+       case TVE_DAC_DIV4_RATE:
+               return parent_rate / 4;
+       case TVE_DAC_DIV2_RATE:
+               return parent_rate / 2;
+       case TVE_DAC_FULL_RATE:
+       default:
+               return parent_rate;
+       }
+
+       return 0;
+}
+
+static long clk_tve_di_round_rate(struct clk_hw *hw, unsigned long rate,
+                                 unsigned long *prate)
+{
+       unsigned long div;
+
+       div = *prate / rate;
+       if (div >= 4)
+               return *prate / 4;
+       else if (div >= 2)
+               return *prate / 2;
+       return *prate;
+}
+
+static int clk_tve_di_set_rate(struct clk_hw *hw, unsigned long rate,
+                              unsigned long parent_rate)
+{
+       struct imx_tve *tve = container_of(hw, struct imx_tve, clk_hw_di);
+       unsigned long div;
+       u32 val;
+       int ret;
+
+       div = parent_rate / rate;
+       if (div >= 4)
+               val = TVE_DAC_DIV4_RATE;
+       else if (div >= 2)
+               val = TVE_DAC_DIV2_RATE;
+       else
+               val = TVE_DAC_FULL_RATE;
+
+       ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG,
+                                TVE_DAC_SAMP_RATE_MASK, val);
+
+       if (ret < 0) {
+               dev_err(tve->dev, "failed to set divider: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static struct clk_ops clk_tve_di_ops = {
+       .round_rate = clk_tve_di_round_rate,
+       .set_rate = clk_tve_di_set_rate,
+       .recalc_rate = clk_tve_di_recalc_rate,
+};
+
+static int tve_clk_init(struct imx_tve *tve, void __iomem *base)
+{
+       const char *tve_di_parent[1];
+       struct clk_init_data init = {
+               .name = "tve_di",
+               .ops = &clk_tve_di_ops,
+               .num_parents = 1,
+               .flags = 0,
+       };
+
+       tve_di_parent[0] = __clk_get_name(tve->clk);
+       init.parent_names = (const char **)&tve_di_parent;
+
+       tve->clk_hw_di.init = &init;
+       tve->di_clk = clk_register(tve->dev, &tve->clk_hw_di);
+       if (IS_ERR(tve->di_clk)) {
+               dev_err(tve->dev, "failed to register TVE output clock: %ld\n",
+                       PTR_ERR(tve->di_clk));
+               return PTR_ERR(tve->di_clk);
+       }
+
+       return 0;
+}
+
+static int imx_tve_register(struct drm_device *drm, struct imx_tve *tve)
+{
+       int encoder_type;
+       int ret;
+
+       encoder_type = tve->mode == TVE_MODE_VGA ?
+                               DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC;
+
+       ret = imx_drm_encoder_parse_of(drm, &tve->encoder,
+                                      tve->dev->of_node);
+       if (ret)
+               return ret;
+
+       drm_encoder_helper_add(&tve->encoder, &imx_tve_encoder_helper_funcs);
+       drm_encoder_init(drm, &tve->encoder, &imx_tve_encoder_funcs,
+                        encoder_type);
+
+       drm_connector_helper_add(&tve->connector,
+                       &imx_tve_connector_helper_funcs);
+       drm_connector_init(drm, &tve->connector, &imx_tve_connector_funcs,
+                          DRM_MODE_CONNECTOR_VGA);
+
+       drm_mode_connector_attach_encoder(&tve->connector, &tve->encoder);
+
+       return 0;
+}
+
+static bool imx_tve_readable_reg(struct device *dev, unsigned int reg)
+{
+       return (reg % 4 == 0) && (reg <= 0xdc);
+}
+
+static struct regmap_config tve_regmap_config = {
+       .reg_bits = 32,
+       .val_bits = 32,
+       .reg_stride = 4,
+
+       .readable_reg = imx_tve_readable_reg,
+
+       .lock = tve_lock,
+       .unlock = tve_unlock,
+
+       .max_register = 0xdc,
+};
+
+static const char * const imx_tve_modes[] = {
+       [TVE_MODE_TVOUT]  = "tvout",
+       [TVE_MODE_VGA] = "vga",
+};
+
+static const int of_get_tve_mode(struct device_node *np)
+{
+       const char *bm;
+       int ret, i;
+
+       ret = of_property_read_string(np, "fsl,tve-mode", &bm);
+       if (ret < 0)
+               return ret;
+
+       for (i = 0; i < ARRAY_SIZE(imx_tve_modes); i++)
+               if (!strcasecmp(bm, imx_tve_modes[i]))
+                       return i;
+
+       return -EINVAL;
+}
+
+static int imx_tve_bind(struct device *dev, struct device *master, void *data)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct drm_device *drm = data;
+       struct device_node *np = dev->of_node;
+       struct device_node *ddc_node;
+       struct imx_tve *tve;
+       struct resource *res;
+       void __iomem *base;
+       unsigned int val;
+       int irq;
+       int ret;
+
+       tve = devm_kzalloc(dev, sizeof(*tve), GFP_KERNEL);
+       if (!tve)
+               return -ENOMEM;
+
+       tve->dev = dev;
+       spin_lock_init(&tve->lock);
+
+       ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
+       if (ddc_node) {
+               tve->ddc = of_find_i2c_adapter_by_node(ddc_node);
+               of_node_put(ddc_node);
+       }
+
+       tve->mode = of_get_tve_mode(np);
+       if (tve->mode != TVE_MODE_VGA) {
+               dev_err(dev, "only VGA mode supported, currently\n");
+               return -EINVAL;
+       }
+
+       if (tve->mode == TVE_MODE_VGA) {
+               ret = of_property_read_u32(np, "fsl,hsync-pin",
+                                          &tve->hsync_pin);
+
+               if (ret < 0) {
+                       dev_err(dev, "failed to get vsync pin\n");
+                       return ret;
+               }
+
+               ret |= of_property_read_u32(np, "fsl,vsync-pin",
+                                           &tve->vsync_pin);
+
+               if (ret < 0) {
+                       dev_err(dev, "failed to get vsync pin\n");
+                       return ret;
+               }
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       tve_regmap_config.lock_arg = tve;
+       tve->regmap = devm_regmap_init_mmio_clk(dev, "tve", base,
+                                               &tve_regmap_config);
+       if (IS_ERR(tve->regmap)) {
+               dev_err(dev, "failed to init regmap: %ld\n",
+                       PTR_ERR(tve->regmap));
+               return PTR_ERR(tve->regmap);
+       }
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(dev, "failed to get irq\n");
+               return irq;
+       }
+
+       ret = devm_request_threaded_irq(dev, irq, NULL,
+                                       imx_tve_irq_handler, IRQF_ONESHOT,
+                                       "imx-tve", tve);
+       if (ret < 0) {
+               dev_err(dev, "failed to request irq: %d\n", ret);
+               return ret;
+       }
+
+       tve->dac_reg = devm_regulator_get(dev, "dac");
+       if (!IS_ERR(tve->dac_reg)) {
+               regulator_set_voltage(tve->dac_reg, 2750000, 2750000);
+               ret = regulator_enable(tve->dac_reg);
+               if (ret)
+                       return ret;
+       }
+
+       tve->clk = devm_clk_get(dev, "tve");
+       if (IS_ERR(tve->clk)) {
+               dev_err(dev, "failed to get high speed tve clock: %ld\n",
+                       PTR_ERR(tve->clk));
+               return PTR_ERR(tve->clk);
+       }
+
+       /* this is the IPU DI clock input selector, can be parented to tve_di */
+       tve->di_sel_clk = devm_clk_get(dev, "di_sel");
+       if (IS_ERR(tve->di_sel_clk)) {
+               dev_err(dev, "failed to get ipu di mux clock: %ld\n",
+                       PTR_ERR(tve->di_sel_clk));
+               return PTR_ERR(tve->di_sel_clk);
+       }
+
+       ret = tve_clk_init(tve, base);
+       if (ret < 0)
+               return ret;
+
+       ret = regmap_read(tve->regmap, TVE_COM_CONF_REG, &val);
+       if (ret < 0) {
+               dev_err(dev, "failed to read configuration register: %d\n", ret);
+               return ret;
+       }
+       if (val != 0x00100000) {
+               dev_err(dev, "configuration register default value indicates this is not a TVEv2\n");
+               return -ENODEV;
+       }
+
+       /* disable cable detection for VGA mode */
+       ret = regmap_write(tve->regmap, TVE_CD_CONT_REG, 0);
+
+       ret = imx_tve_register(drm, tve);
+       if (ret)
+               return ret;
+
+       dev_set_drvdata(dev, tve);
+
+       return 0;
+}
+
+static void imx_tve_unbind(struct device *dev, struct device *master,
+       void *data)
+{
+       struct imx_tve *tve = dev_get_drvdata(dev);
+
+       tve->connector.funcs->destroy(&tve->connector);
+       tve->encoder.funcs->destroy(&tve->encoder);
+
+       if (!IS_ERR(tve->dac_reg))
+               regulator_disable(tve->dac_reg);
+}
+
+static const struct component_ops imx_tve_ops = {
+       .bind   = imx_tve_bind,
+       .unbind = imx_tve_unbind,
+};
+
+static int imx_tve_probe(struct platform_device *pdev)
+{
+       return component_add(&pdev->dev, &imx_tve_ops);
+}
+
+static int imx_tve_remove(struct platform_device *pdev)
+{
+       component_del(&pdev->dev, &imx_tve_ops);
+       return 0;
+}
+
+static const struct of_device_id imx_tve_dt_ids[] = {
+       { .compatible = "fsl,imx53-tve", },
+       { /* sentinel */ }
+};
+
+static struct platform_driver imx_tve_driver = {
+       .probe          = imx_tve_probe,
+       .remove         = imx_tve_remove,
+       .driver         = {
+               .of_match_table = imx_tve_dt_ids,
+               .name   = "imx-tve",
+               .owner  = THIS_MODULE,
+       },
+};
+
+module_platform_driver(imx_tve_driver);
+
+MODULE_DESCRIPTION("i.MX Television Encoder driver");
+MODULE_AUTHOR("Philipp Zabel, Pengutronix");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-tve");
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
new file mode 100644 (file)
index 0000000..11e84a2
--- /dev/null
@@ -0,0 +1,518 @@
+/*
+ * i.MX IPUv3 Graphics driver
+ *
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix
+ *
+ * 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.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#include <linux/component.h>
+#include <linux/module.h>
+#include <linux/export.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <linux/fb.h>
+#include <linux/clk.h>
+#include <linux/errno.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+
+#include <video/imx-ipu-v3.h>
+#include "imx-drm.h"
+#include "ipuv3-plane.h"
+
+#define DRIVER_DESC            "i.MX IPUv3 Graphics"
+
+struct ipu_crtc {
+       struct device           *dev;
+       struct drm_crtc         base;
+       struct imx_drm_crtc     *imx_crtc;
+
+       /* plane[0] is the full plane, plane[1] is the partial plane */
+       struct ipu_plane        *plane[2];
+
+       struct ipu_dc           *dc;
+       struct ipu_di           *di;
+       int                     enabled;
+       struct drm_pending_vblank_event *page_flip_event;
+       struct drm_framebuffer  *newfb;
+       int                     irq;
+       u32                     interface_pix_fmt;
+       unsigned long           di_clkflags;
+       int                     di_hsync_pin;
+       int                     di_vsync_pin;
+};
+
+#define to_ipu_crtc(x) container_of(x, struct ipu_crtc, base)
+
+static void ipu_fb_enable(struct ipu_crtc *ipu_crtc)
+{
+       struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
+
+       if (ipu_crtc->enabled)
+               return;
+
+       ipu_dc_enable(ipu);
+       ipu_plane_enable(ipu_crtc->plane[0]);
+       /* Start DC channel and DI after IDMAC */
+       ipu_dc_enable_channel(ipu_crtc->dc);
+       ipu_di_enable(ipu_crtc->di);
+
+       ipu_crtc->enabled = 1;
+}
+
+static void ipu_fb_disable(struct ipu_crtc *ipu_crtc)
+{
+       struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
+
+       if (!ipu_crtc->enabled)
+               return;
+
+       /* Stop DC channel and DI before IDMAC */
+       ipu_dc_disable_channel(ipu_crtc->dc);
+       ipu_di_disable(ipu_crtc->di);
+       ipu_plane_disable(ipu_crtc->plane[0]);
+       ipu_dc_disable(ipu);
+
+       ipu_crtc->enabled = 0;
+}
+
+static void ipu_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+
+       dev_dbg(ipu_crtc->dev, "%s mode: %d\n", __func__, mode);
+
+       switch (mode) {
+       case DRM_MODE_DPMS_ON:
+               ipu_fb_enable(ipu_crtc);
+               break;
+       case DRM_MODE_DPMS_STANDBY:
+       case DRM_MODE_DPMS_SUSPEND:
+       case DRM_MODE_DPMS_OFF:
+               ipu_fb_disable(ipu_crtc);
+               break;
+       }
+}
+
+static int ipu_page_flip(struct drm_crtc *crtc,
+               struct drm_framebuffer *fb,
+               struct drm_pending_vblank_event *event,
+               uint32_t page_flip_flags)
+{
+       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+       int ret;
+
+       if (ipu_crtc->newfb)
+               return -EBUSY;
+
+       ret = imx_drm_crtc_vblank_get(ipu_crtc->imx_crtc);
+       if (ret) {
+               dev_dbg(ipu_crtc->dev, "failed to acquire vblank counter\n");
+               list_del(&event->base.link);
+
+               return ret;
+       }
+
+       ipu_crtc->newfb = fb;
+       ipu_crtc->page_flip_event = event;
+       crtc->primary->fb = fb;
+
+       return 0;
+}
+
+static const struct drm_crtc_funcs ipu_crtc_funcs = {
+       .set_config = drm_crtc_helper_set_config,
+       .destroy = drm_crtc_cleanup,
+       .page_flip = ipu_page_flip,
+};
+
+static int ipu_crtc_mode_set(struct drm_crtc *crtc,
+                              struct drm_display_mode *orig_mode,
+                              struct drm_display_mode *mode,
+                              int x, int y,
+                              struct drm_framebuffer *old_fb)
+{
+       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+       int ret;
+       struct ipu_di_signal_cfg sig_cfg = {};
+       u32 out_pixel_fmt;
+
+       dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__,
+                       mode->hdisplay);
+       dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__,
+                       mode->vdisplay);
+
+       out_pixel_fmt = ipu_crtc->interface_pix_fmt;
+
+       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+               sig_cfg.interlaced = 1;
+       if (mode->flags & DRM_MODE_FLAG_PHSYNC)
+               sig_cfg.Hsync_pol = 1;
+       if (mode->flags & DRM_MODE_FLAG_PVSYNC)
+               sig_cfg.Vsync_pol = 1;
+
+       sig_cfg.enable_pol = 1;
+       sig_cfg.clk_pol = 0;
+       sig_cfg.width = mode->hdisplay;
+       sig_cfg.height = mode->vdisplay;
+       sig_cfg.pixel_fmt = out_pixel_fmt;
+       sig_cfg.h_start_width = mode->htotal - mode->hsync_end;
+       sig_cfg.h_sync_width = mode->hsync_end - mode->hsync_start;
+       sig_cfg.h_end_width = mode->hsync_start - mode->hdisplay;
+
+       sig_cfg.v_start_width = mode->vtotal - mode->vsync_end;
+       sig_cfg.v_sync_width = mode->vsync_end - mode->vsync_start;
+       sig_cfg.v_end_width = mode->vsync_start - mode->vdisplay;
+       sig_cfg.pixelclock = mode->clock * 1000;
+       sig_cfg.clkflags = ipu_crtc->di_clkflags;
+
+       sig_cfg.v_to_h_sync = 0;
+
+       sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin;
+       sig_cfg.vsync_pin = ipu_crtc->di_vsync_pin;
+
+       ret = ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di, sig_cfg.interlaced,
+                       out_pixel_fmt, mode->hdisplay);
+       if (ret) {
+               dev_err(ipu_crtc->dev,
+                               "initializing display controller failed with %d\n",
+                               ret);
+               return ret;
+       }
+
+       ret = ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg);
+       if (ret) {
+               dev_err(ipu_crtc->dev,
+                               "initializing panel failed with %d\n", ret);
+               return ret;
+       }
+
+       return ipu_plane_mode_set(ipu_crtc->plane[0], crtc, mode,
+                                 crtc->primary->fb,
+                                 0, 0, mode->hdisplay, mode->vdisplay,
+                                 x, y, mode->hdisplay, mode->vdisplay);
+}
+
+static void ipu_crtc_handle_pageflip(struct ipu_crtc *ipu_crtc)
+{
+       unsigned long flags;
+       struct drm_device *drm = ipu_crtc->base.dev;
+
+       spin_lock_irqsave(&drm->event_lock, flags);
+       if (ipu_crtc->page_flip_event)
+               drm_send_vblank_event(drm, -1, ipu_crtc->page_flip_event);
+       ipu_crtc->page_flip_event = NULL;
+       imx_drm_crtc_vblank_put(ipu_crtc->imx_crtc);
+       spin_unlock_irqrestore(&drm->event_lock, flags);
+}
+
+static irqreturn_t ipu_irq_handler(int irq, void *dev_id)
+{
+       struct ipu_crtc *ipu_crtc = dev_id;
+
+       imx_drm_handle_vblank(ipu_crtc->imx_crtc);
+
+       if (ipu_crtc->newfb) {
+               struct ipu_plane *plane = ipu_crtc->plane[0];
+
+               ipu_crtc->newfb = NULL;
+               ipu_plane_set_base(plane, ipu_crtc->base.primary->fb,
+                                  plane->x, plane->y);
+               ipu_crtc_handle_pageflip(ipu_crtc);
+       }
+
+       return IRQ_HANDLED;
+}
+
+static bool ipu_crtc_mode_fixup(struct drm_crtc *crtc,
+                                 const struct drm_display_mode *mode,
+                                 struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+static void ipu_crtc_prepare(struct drm_crtc *crtc)
+{
+       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+
+       ipu_fb_disable(ipu_crtc);
+}
+
+static void ipu_crtc_commit(struct drm_crtc *crtc)
+{
+       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+
+       ipu_fb_enable(ipu_crtc);
+}
+
+static struct drm_crtc_helper_funcs ipu_helper_funcs = {
+       .dpms = ipu_crtc_dpms,
+       .mode_fixup = ipu_crtc_mode_fixup,
+       .mode_set = ipu_crtc_mode_set,
+       .prepare = ipu_crtc_prepare,
+       .commit = ipu_crtc_commit,
+};
+
+static int ipu_enable_vblank(struct drm_crtc *crtc)
+{
+       return 0;
+}
+
+static void ipu_disable_vblank(struct drm_crtc *crtc)
+{
+       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+
+       ipu_crtc->page_flip_event = NULL;
+       ipu_crtc->newfb = NULL;
+}
+
+static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type,
+               u32 pixfmt, int hsync_pin, int vsync_pin)
+{
+       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+
+       ipu_crtc->interface_pix_fmt = pixfmt;
+       ipu_crtc->di_hsync_pin = hsync_pin;
+       ipu_crtc->di_vsync_pin = vsync_pin;
+
+       switch (encoder_type) {
+       case DRM_MODE_ENCODER_DAC:
+       case DRM_MODE_ENCODER_TVDAC:
+       case DRM_MODE_ENCODER_LVDS:
+               ipu_crtc->di_clkflags = IPU_DI_CLKMODE_SYNC |
+                       IPU_DI_CLKMODE_EXT;
+               break;
+       case DRM_MODE_ENCODER_TMDS:
+       case DRM_MODE_ENCODER_NONE:
+               ipu_crtc->di_clkflags = 0;
+               break;
+       }
+
+       return 0;
+}
+
+static const struct imx_drm_crtc_helper_funcs ipu_crtc_helper_funcs = {
+       .enable_vblank = ipu_enable_vblank,
+       .disable_vblank = ipu_disable_vblank,
+       .set_interface_pix_fmt = ipu_set_interface_pix_fmt,
+       .crtc_funcs = &ipu_crtc_funcs,
+       .crtc_helper_funcs = &ipu_helper_funcs,
+};
+
+static void ipu_put_resources(struct ipu_crtc *ipu_crtc)
+{
+       if (!IS_ERR_OR_NULL(ipu_crtc->dc))
+               ipu_dc_put(ipu_crtc->dc);
+       if (!IS_ERR_OR_NULL(ipu_crtc->di))
+               ipu_di_put(ipu_crtc->di);
+}
+
+static int ipu_get_resources(struct ipu_crtc *ipu_crtc,
+               struct ipu_client_platformdata *pdata)
+{
+       struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
+       int ret;
+
+       ipu_crtc->dc = ipu_dc_get(ipu, pdata->dc);
+       if (IS_ERR(ipu_crtc->dc)) {
+               ret = PTR_ERR(ipu_crtc->dc);
+               goto err_out;
+       }
+
+       ipu_crtc->di = ipu_di_get(ipu, pdata->di);
+       if (IS_ERR(ipu_crtc->di)) {
+               ret = PTR_ERR(ipu_crtc->di);
+               goto err_out;
+       }
+
+       return 0;
+err_out:
+       ipu_put_resources(ipu_crtc);
+
+       return ret;
+}
+
+static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
+       struct ipu_client_platformdata *pdata, struct drm_device *drm)
+{
+       struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
+       int dp = -EINVAL;
+       int ret;
+       int id;
+
+       ret = ipu_get_resources(ipu_crtc, pdata);
+       if (ret) {
+               dev_err(ipu_crtc->dev, "getting resources failed with %d.\n",
+                               ret);
+               return ret;
+       }
+
+       ret = imx_drm_add_crtc(drm, &ipu_crtc->base, &ipu_crtc->imx_crtc,
+                       &ipu_crtc_helper_funcs, ipu_crtc->dev->of_node);
+       if (ret) {
+               dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret);
+               goto err_put_resources;
+       }
+
+       if (pdata->dp >= 0)
+               dp = IPU_DP_FLOW_SYNC_BG;
+       id = imx_drm_crtc_id(ipu_crtc->imx_crtc);
+       ipu_crtc->plane[0] = ipu_plane_init(ipu_crtc->base.dev, ipu,
+                                           pdata->dma[0], dp, BIT(id), true);
+       ret = ipu_plane_get_resources(ipu_crtc->plane[0]);
+       if (ret) {
+               dev_err(ipu_crtc->dev, "getting plane 0 resources failed with %d.\n",
+                       ret);
+               goto err_remove_crtc;
+       }
+
+       /* If this crtc is using the DP, add an overlay plane */
+       if (pdata->dp >= 0 && pdata->dma[1] > 0) {
+               ipu_crtc->plane[1] = ipu_plane_init(ipu_crtc->base.dev, ipu,
+                                                   pdata->dma[1],
+                                                   IPU_DP_FLOW_SYNC_FG,
+                                                   BIT(id), false);
+               if (IS_ERR(ipu_crtc->plane[1]))
+                       ipu_crtc->plane[1] = NULL;
+       }
+
+       ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]);
+       ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0,
+                       "imx_drm", ipu_crtc);
+       if (ret < 0) {
+               dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
+               goto err_put_plane_res;
+       }
+
+       return 0;
+
+err_put_plane_res:
+       ipu_plane_put_resources(ipu_crtc->plane[0]);
+err_remove_crtc:
+       imx_drm_remove_crtc(ipu_crtc->imx_crtc);
+err_put_resources:
+       ipu_put_resources(ipu_crtc);
+
+       return ret;
+}
+
+static struct device_node *ipu_drm_get_port_by_id(struct device_node *parent,
+                                                 int port_id)
+{
+       struct device_node *port;
+       int id, ret;
+
+       port = of_get_child_by_name(parent, "port");
+       while (port) {
+               ret = of_property_read_u32(port, "reg", &id);
+               if (!ret && id == port_id)
+                       return port;
+
+               do {
+                       port = of_get_next_child(parent, port);
+                       if (!port)
+                               return NULL;
+               } while (of_node_cmp(port->name, "port"));
+       }
+
+       return NULL;
+}
+
+static int ipu_drm_bind(struct device *dev, struct device *master, void *data)
+{
+       struct ipu_client_platformdata *pdata = dev->platform_data;
+       struct drm_device *drm = data;
+       struct ipu_crtc *ipu_crtc;
+       int ret;
+
+       ipu_crtc = devm_kzalloc(dev, sizeof(*ipu_crtc), GFP_KERNEL);
+       if (!ipu_crtc)
+               return -ENOMEM;
+
+       ipu_crtc->dev = dev;
+
+       ret = ipu_crtc_init(ipu_crtc, pdata, drm);
+       if (ret)
+               return ret;
+
+       dev_set_drvdata(dev, ipu_crtc);
+
+       return 0;
+}
+
+static void ipu_drm_unbind(struct device *dev, struct device *master,
+       void *data)
+{
+       struct ipu_crtc *ipu_crtc = dev_get_drvdata(dev);
+
+       imx_drm_remove_crtc(ipu_crtc->imx_crtc);
+
+       ipu_plane_put_resources(ipu_crtc->plane[0]);
+       ipu_put_resources(ipu_crtc);
+}
+
+static const struct component_ops ipu_crtc_ops = {
+       .bind = ipu_drm_bind,
+       .unbind = ipu_drm_unbind,
+};
+
+static int ipu_drm_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct ipu_client_platformdata *pdata = dev->platform_data;
+       int ret;
+
+       if (!dev->platform_data)
+               return -EINVAL;
+
+       if (!dev->of_node) {
+               /* Associate crtc device with the corresponding DI port node */
+               dev->of_node = ipu_drm_get_port_by_id(dev->parent->of_node,
+                                                     pdata->di + 2);
+               if (!dev->of_node) {
+                       dev_err(dev, "missing port@%d node in %s\n",
+                               pdata->di + 2, dev->parent->of_node->full_name);
+                       return -ENODEV;
+               }
+       }
+
+       ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
+       if (ret)
+               return ret;
+
+       return component_add(dev, &ipu_crtc_ops);
+}
+
+static int ipu_drm_remove(struct platform_device *pdev)
+{
+       component_del(&pdev->dev, &ipu_crtc_ops);
+       return 0;
+}
+
+static struct platform_driver ipu_drm_driver = {
+       .driver = {
+               .name = "imx-ipuv3-crtc",
+       },
+       .probe = ipu_drm_probe,
+       .remove = ipu_drm_remove,
+};
+module_platform_driver(ipu_drm_driver);
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-ipuv3-crtc");
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
new file mode 100644 (file)
index 0000000..944962b
--- /dev/null
@@ -0,0 +1,363 @@
+/*
+ * i.MX IPUv3 DP Overlay Planes
+ *
+ * Copyright (C) 2013 Philipp Zabel, Pengutronix
+ *
+ * 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.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+
+#include "video/imx-ipu-v3.h"
+#include "ipuv3-plane.h"
+
+#define to_ipu_plane(x)        container_of(x, struct ipu_plane, base)
+
+static const uint32_t ipu_plane_formats[] = {
+       DRM_FORMAT_XRGB1555,
+       DRM_FORMAT_XBGR1555,
+       DRM_FORMAT_ARGB8888,
+       DRM_FORMAT_XRGB8888,
+       DRM_FORMAT_ABGR8888,
+       DRM_FORMAT_XBGR8888,
+       DRM_FORMAT_YUYV,
+       DRM_FORMAT_YVYU,
+       DRM_FORMAT_YUV420,
+       DRM_FORMAT_YVU420,
+};
+
+int ipu_plane_irq(struct ipu_plane *ipu_plane)
+{
+       return ipu_idmac_channel_irq(ipu_plane->ipu, ipu_plane->ipu_ch,
+                                    IPU_IRQ_EOF);
+}
+
+static int calc_vref(struct drm_display_mode *mode)
+{
+       unsigned long htotal, vtotal;
+
+       htotal = mode->htotal;
+       vtotal = mode->vtotal;
+
+       if (!htotal || !vtotal)
+               return 60;
+
+       return DIV_ROUND_UP(mode->clock * 1000, vtotal * htotal);
+}
+
+static inline int calc_bandwidth(int width, int height, unsigned int vref)
+{
+       return width * height * vref;
+}
+
+int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb,
+                      int x, int y)
+{
+       struct drm_gem_cma_object *cma_obj;
+       unsigned long eba;
+
+       cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
+       if (!cma_obj) {
+               DRM_DEBUG_KMS("entry is null.\n");
+               return -EFAULT;
+       }
+
+       dev_dbg(ipu_plane->base.dev->dev, "phys = %pad, x = %d, y = %d",
+               &cma_obj->paddr, x, y);
+
+       ipu_cpmem_set_stride(ipu_plane->ipu_ch, fb->pitches[0]);
+
+       eba = cma_obj->paddr + fb->offsets[0] +
+             fb->pitches[0] * y + (fb->bits_per_pixel >> 3) * x;
+       ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 0, eba);
+       ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, eba);
+
+       /* cache offsets for subsequent pageflips */
+       ipu_plane->x = x;
+       ipu_plane->y = y;
+
+       return 0;
+}
+
+int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc,
+                      struct drm_display_mode *mode,
+                      struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+                      unsigned int crtc_w, unsigned int crtc_h,
+                      uint32_t src_x, uint32_t src_y,
+                      uint32_t src_w, uint32_t src_h)
+{
+       struct device *dev = ipu_plane->base.dev->dev;
+       int ret;
+
+       /* no scaling */
+       if (src_w != crtc_w || src_h != crtc_h)
+               return -EINVAL;
+
+       /* clip to crtc bounds */
+       if (crtc_x < 0) {
+               if (-crtc_x > crtc_w)
+                       return -EINVAL;
+               src_x += -crtc_x;
+               src_w -= -crtc_x;
+               crtc_w -= -crtc_x;
+               crtc_x = 0;
+       }
+       if (crtc_y < 0) {
+               if (-crtc_y > crtc_h)
+                       return -EINVAL;
+               src_y += -crtc_y;
+               src_h -= -crtc_y;
+               crtc_h -= -crtc_y;
+               crtc_y = 0;
+       }
+       if (crtc_x + crtc_w > mode->hdisplay) {
+               if (crtc_x > mode->hdisplay)
+                       return -EINVAL;
+               crtc_w = mode->hdisplay - crtc_x;
+               src_w = crtc_w;
+       }
+       if (crtc_y + crtc_h > mode->vdisplay) {
+               if (crtc_y > mode->vdisplay)
+                       return -EINVAL;
+               crtc_h = mode->vdisplay - crtc_y;
+               src_h = crtc_h;
+       }
+       /* full plane minimum width is 13 pixels */
+       if (crtc_w < 13 && (ipu_plane->dp_flow != IPU_DP_FLOW_SYNC_FG))
+               return -EINVAL;
+       if (crtc_h < 2)
+               return -EINVAL;
+
+       switch (ipu_plane->dp_flow) {
+       case IPU_DP_FLOW_SYNC_BG:
+               ret = ipu_dp_setup_channel(ipu_plane->dp,
+                               IPUV3_COLORSPACE_RGB,
+                               IPUV3_COLORSPACE_RGB);
+               if (ret) {
+                       dev_err(dev,
+                               "initializing display processor failed with %d\n",
+                               ret);
+                       return ret;
+               }
+               ipu_dp_set_global_alpha(ipu_plane->dp, 1, 0, 1);
+               break;
+       case IPU_DP_FLOW_SYNC_FG:
+               ipu_dp_setup_channel(ipu_plane->dp,
+                               ipu_drm_fourcc_to_colorspace(fb->pixel_format),
+                               IPUV3_COLORSPACE_UNKNOWN);
+               ipu_dp_set_window_pos(ipu_plane->dp, crtc_x, crtc_y);
+               break;
+       }
+
+       ret = ipu_dmfc_init_channel(ipu_plane->dmfc, crtc_w);
+       if (ret) {
+               dev_err(dev, "initializing dmfc channel failed with %d\n", ret);
+               return ret;
+       }
+
+       ret = ipu_dmfc_alloc_bandwidth(ipu_plane->dmfc,
+                       calc_bandwidth(crtc_w, crtc_h,
+                                      calc_vref(mode)), 64);
+       if (ret) {
+               dev_err(dev, "allocating dmfc bandwidth failed with %d\n", ret);
+               return ret;
+       }
+
+       ipu_cpmem_zero(ipu_plane->ipu_ch);
+       ipu_cpmem_set_resolution(ipu_plane->ipu_ch, src_w, src_h);
+       ret = ipu_cpmem_set_fmt(ipu_plane->ipu_ch, fb->pixel_format);
+       if (ret < 0) {
+               dev_err(dev, "unsupported pixel format 0x%08x\n",
+                       fb->pixel_format);
+               return ret;
+       }
+       ipu_cpmem_set_high_priority(ipu_plane->ipu_ch);
+
+       ret = ipu_plane_set_base(ipu_plane, fb, src_x, src_y);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+void ipu_plane_put_resources(struct ipu_plane *ipu_plane)
+{
+       if (!IS_ERR_OR_NULL(ipu_plane->dp))
+               ipu_dp_put(ipu_plane->dp);
+       if (!IS_ERR_OR_NULL(ipu_plane->dmfc))
+               ipu_dmfc_put(ipu_plane->dmfc);
+       if (!IS_ERR_OR_NULL(ipu_plane->ipu_ch))
+               ipu_idmac_put(ipu_plane->ipu_ch);
+}
+
+int ipu_plane_get_resources(struct ipu_plane *ipu_plane)
+{
+       int ret;
+
+       ipu_plane->ipu_ch = ipu_idmac_get(ipu_plane->ipu, ipu_plane->dma);
+       if (IS_ERR(ipu_plane->ipu_ch)) {
+               ret = PTR_ERR(ipu_plane->ipu_ch);
+               DRM_ERROR("failed to get idmac channel: %d\n", ret);
+               return ret;
+       }
+
+       ipu_plane->dmfc = ipu_dmfc_get(ipu_plane->ipu, ipu_plane->dma);
+       if (IS_ERR(ipu_plane->dmfc)) {
+               ret = PTR_ERR(ipu_plane->dmfc);
+               DRM_ERROR("failed to get dmfc: ret %d\n", ret);
+               goto err_out;
+       }
+
+       if (ipu_plane->dp_flow >= 0) {
+               ipu_plane->dp = ipu_dp_get(ipu_plane->ipu, ipu_plane->dp_flow);
+               if (IS_ERR(ipu_plane->dp)) {
+                       ret = PTR_ERR(ipu_plane->dp);
+                       DRM_ERROR("failed to get dp flow: %d\n", ret);
+                       goto err_out;
+               }
+       }
+
+       return 0;
+err_out:
+       ipu_plane_put_resources(ipu_plane);
+
+       return ret;
+}
+
+void ipu_plane_enable(struct ipu_plane *ipu_plane)
+{
+       if (ipu_plane->dp)
+               ipu_dp_enable(ipu_plane->ipu);
+       ipu_dmfc_enable_channel(ipu_plane->dmfc);
+       ipu_idmac_enable_channel(ipu_plane->ipu_ch);
+       if (ipu_plane->dp)
+               ipu_dp_enable_channel(ipu_plane->dp);
+
+       ipu_plane->enabled = true;
+}
+
+void ipu_plane_disable(struct ipu_plane *ipu_plane)
+{
+       ipu_plane->enabled = false;
+
+       ipu_idmac_wait_busy(ipu_plane->ipu_ch, 50);
+
+       if (ipu_plane->dp)
+               ipu_dp_disable_channel(ipu_plane->dp);
+       ipu_idmac_disable_channel(ipu_plane->ipu_ch);
+       ipu_dmfc_disable_channel(ipu_plane->dmfc);
+       if (ipu_plane->dp)
+               ipu_dp_disable(ipu_plane->ipu);
+}
+
+/*
+ * drm_plane API
+ */
+
+static int ipu_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
+                           struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+                           unsigned int crtc_w, unsigned int crtc_h,
+                           uint32_t src_x, uint32_t src_y,
+                           uint32_t src_w, uint32_t src_h)
+{
+       struct ipu_plane *ipu_plane = to_ipu_plane(plane);
+       int ret = 0;
+
+       DRM_DEBUG_KMS("plane - %p\n", plane);
+
+       if (!ipu_plane->enabled)
+               ret = ipu_plane_get_resources(ipu_plane);
+       if (ret < 0)
+               return ret;
+
+       ret = ipu_plane_mode_set(ipu_plane, crtc, &crtc->hwmode, fb,
+                       crtc_x, crtc_y, crtc_w, crtc_h,
+                       src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16);
+       if (ret < 0) {
+               ipu_plane_put_resources(ipu_plane);
+               return ret;
+       }
+
+       if (crtc != plane->crtc)
+               dev_info(plane->dev->dev, "crtc change: %p -> %p\n",
+                               plane->crtc, crtc);
+       plane->crtc = crtc;
+
+       if (!ipu_plane->enabled)
+               ipu_plane_enable(ipu_plane);
+
+       return 0;
+}
+
+static int ipu_disable_plane(struct drm_plane *plane)
+{
+       struct ipu_plane *ipu_plane = to_ipu_plane(plane);
+
+       DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+
+       if (ipu_plane->enabled)
+               ipu_plane_disable(ipu_plane);
+
+       ipu_plane_put_resources(ipu_plane);
+
+       return 0;
+}
+
+static void ipu_plane_destroy(struct drm_plane *plane)
+{
+       struct ipu_plane *ipu_plane = to_ipu_plane(plane);
+
+       DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
+
+       ipu_disable_plane(plane);
+       drm_plane_cleanup(plane);
+       kfree(ipu_plane);
+}
+
+static struct drm_plane_funcs ipu_plane_funcs = {
+       .update_plane   = ipu_update_plane,
+       .disable_plane  = ipu_disable_plane,
+       .destroy        = ipu_plane_destroy,
+};
+
+struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
+                                int dma, int dp, unsigned int possible_crtcs,
+                                bool priv)
+{
+       struct ipu_plane *ipu_plane;
+       int ret;
+
+       DRM_DEBUG_KMS("channel %d, dp flow %d, possible_crtcs=0x%x\n",
+                     dma, dp, possible_crtcs);
+
+       ipu_plane = kzalloc(sizeof(*ipu_plane), GFP_KERNEL);
+       if (!ipu_plane) {
+               DRM_ERROR("failed to allocate plane\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       ipu_plane->ipu = ipu;
+       ipu_plane->dma = dma;
+       ipu_plane->dp_flow = dp;
+
+       ret = drm_plane_init(dev, &ipu_plane->base, possible_crtcs,
+                            &ipu_plane_funcs, ipu_plane_formats,
+                            ARRAY_SIZE(ipu_plane_formats),
+                            priv);
+       if (ret) {
+               DRM_ERROR("failed to initialize plane\n");
+               kfree(ipu_plane);
+               return ERR_PTR(ret);
+       }
+
+       return ipu_plane;
+}
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.h b/drivers/gpu/drm/imx/ipuv3-plane.h
new file mode 100644 (file)
index 0000000..c0aae5b
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef __IPUV3_PLANE_H__
+#define __IPUV3_PLANE_H__
+
+#include <drm/drm_crtc.h> /* drm_plane */
+
+struct drm_plane;
+struct drm_device;
+struct ipu_soc;
+struct drm_crtc;
+struct drm_framebuffer;
+
+struct ipuv3_channel;
+struct dmfc_channel;
+struct ipu_dp;
+
+struct ipu_plane {
+       struct drm_plane        base;
+
+       struct ipu_soc          *ipu;
+       struct ipuv3_channel    *ipu_ch;
+       struct dmfc_channel     *dmfc;
+       struct ipu_dp           *dp;
+
+       int                     dma;
+       int                     dp_flow;
+
+       int                     x;
+       int                     y;
+
+       bool                    enabled;
+};
+
+struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
+                                int dma, int dp, unsigned int possible_crtcs,
+                                bool priv);
+
+/* Init IDMAC, DMFC, DP */
+int ipu_plane_mode_set(struct ipu_plane *plane, struct drm_crtc *crtc,
+                      struct drm_display_mode *mode,
+                      struct drm_framebuffer *fb, int crtc_x, int crtc_y,
+                      unsigned int crtc_w, unsigned int crtc_h,
+                      uint32_t src_x, uint32_t src_y, uint32_t src_w,
+                      uint32_t src_h);
+
+void ipu_plane_enable(struct ipu_plane *plane);
+void ipu_plane_disable(struct ipu_plane *plane);
+int ipu_plane_set_base(struct ipu_plane *plane, struct drm_framebuffer *fb,
+                      int x, int y);
+
+int ipu_plane_get_resources(struct ipu_plane *plane);
+void ipu_plane_put_resources(struct ipu_plane *plane);
+
+int ipu_plane_irq(struct ipu_plane *plane);
+
+#endif
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
new file mode 100644 (file)
index 0000000..015a454
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * i.MX drm driver - parallel display implementation
+ *
+ * Copyright (C) 2012 Sascha Hauer, Pengutronix
+ *
+ * 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.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/component.h>
+#include <linux/module.h>
+#include <drm/drmP.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_panel.h>
+#include <linux/videodev2.h>
+#include <video/of_display_timing.h>
+
+#include "imx-drm.h"
+
+#define con_to_imxpd(x) container_of(x, struct imx_parallel_display, connector)
+#define enc_to_imxpd(x) container_of(x, struct imx_parallel_display, encoder)
+
+struct imx_parallel_display {
+       struct drm_connector connector;
+       struct drm_encoder encoder;
+       struct device *dev;
+       void *edid;
+       int edid_len;
+       u32 interface_pix_fmt;
+       int mode_valid;
+       struct drm_display_mode mode;
+       struct drm_panel *panel;
+};
+
+static enum drm_connector_status imx_pd_connector_detect(
+               struct drm_connector *connector, bool force)
+{
+       return connector_status_connected;
+}
+
+static int imx_pd_connector_get_modes(struct drm_connector *connector)
+{
+       struct imx_parallel_display *imxpd = con_to_imxpd(connector);
+       struct device_node *np = imxpd->dev->of_node;
+       int num_modes = 0;
+
+       if (imxpd->panel && imxpd->panel->funcs &&
+           imxpd->panel->funcs->get_modes) {
+               num_modes = imxpd->panel->funcs->get_modes(imxpd->panel);
+               if (num_modes > 0)
+                       return num_modes;
+       }
+
+       if (imxpd->edid) {
+               drm_mode_connector_update_edid_property(connector, imxpd->edid);
+               num_modes = drm_add_edid_modes(connector, imxpd->edid);
+       }
+
+       if (imxpd->mode_valid) {
+               struct drm_display_mode *mode = drm_mode_create(connector->dev);
+
+               if (!mode)
+                       return -EINVAL;
+               drm_mode_copy(mode, &imxpd->mode);
+               mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+               drm_mode_probed_add(connector, mode);
+               num_modes++;
+       }
+
+       if (np) {
+               struct drm_display_mode *mode = drm_mode_create(connector->dev);
+
+               if (!mode)
+                       return -EINVAL;
+               of_get_drm_display_mode(np, &imxpd->mode, OF_USE_NATIVE_MODE);
+               drm_mode_copy(mode, &imxpd->mode);
+               mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+               drm_mode_probed_add(connector, mode);
+               num_modes++;
+       }
+
+       return num_modes;
+}
+
+static struct drm_encoder *imx_pd_connector_best_encoder(
+               struct drm_connector *connector)
+{
+       struct imx_parallel_display *imxpd = con_to_imxpd(connector);
+
+       return &imxpd->encoder;
+}
+
+static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+       struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
+
+       if (mode != DRM_MODE_DPMS_ON)
+               drm_panel_disable(imxpd->panel);
+       else
+               drm_panel_enable(imxpd->panel);
+}
+
+static bool imx_pd_encoder_mode_fixup(struct drm_encoder *encoder,
+                          const struct drm_display_mode *mode,
+                          struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+static void imx_pd_encoder_prepare(struct drm_encoder *encoder)
+{
+       struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
+
+       imx_drm_panel_format(encoder, imxpd->interface_pix_fmt);
+}
+
+static void imx_pd_encoder_commit(struct drm_encoder *encoder)
+{
+}
+
+static void imx_pd_encoder_mode_set(struct drm_encoder *encoder,
+                        struct drm_display_mode *mode,
+                        struct drm_display_mode *adjusted_mode)
+{
+}
+
+static void imx_pd_encoder_disable(struct drm_encoder *encoder)
+{
+}
+
+static struct drm_connector_funcs imx_pd_connector_funcs = {
+       .dpms = drm_helper_connector_dpms,
+       .fill_modes = drm_helper_probe_single_connector_modes,
+       .detect = imx_pd_connector_detect,
+       .destroy = imx_drm_connector_destroy,
+};
+
+static struct drm_connector_helper_funcs imx_pd_connector_helper_funcs = {
+       .get_modes = imx_pd_connector_get_modes,
+       .best_encoder = imx_pd_connector_best_encoder,
+};
+
+static struct drm_encoder_funcs imx_pd_encoder_funcs = {
+       .destroy = imx_drm_encoder_destroy,
+};
+
+static struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = {
+       .dpms = imx_pd_encoder_dpms,
+       .mode_fixup = imx_pd_encoder_mode_fixup,
+       .prepare = imx_pd_encoder_prepare,
+       .commit = imx_pd_encoder_commit,
+       .mode_set = imx_pd_encoder_mode_set,
+       .disable = imx_pd_encoder_disable,
+};
+
+static int imx_pd_register(struct drm_device *drm,
+       struct imx_parallel_display *imxpd)
+{
+       int ret;
+
+       ret = imx_drm_encoder_parse_of(drm, &imxpd->encoder,
+                                      imxpd->dev->of_node);
+       if (ret)
+               return ret;
+
+       /* set the connector's dpms to OFF so that
+        * drm_helper_connector_dpms() won't return
+        * immediately since the current state is ON
+        * at this point.
+        */
+       imxpd->connector.dpms = DRM_MODE_DPMS_OFF;
+
+       drm_encoder_helper_add(&imxpd->encoder, &imx_pd_encoder_helper_funcs);
+       drm_encoder_init(drm, &imxpd->encoder, &imx_pd_encoder_funcs,
+                        DRM_MODE_ENCODER_NONE);
+
+       drm_connector_helper_add(&imxpd->connector,
+                       &imx_pd_connector_helper_funcs);
+       drm_connector_init(drm, &imxpd->connector, &imx_pd_connector_funcs,
+                          DRM_MODE_CONNECTOR_VGA);
+
+       if (imxpd->panel)
+               drm_panel_attach(imxpd->panel, &imxpd->connector);
+
+       drm_mode_connector_attach_encoder(&imxpd->connector, &imxpd->encoder);
+
+       imxpd->connector.encoder = &imxpd->encoder;
+
+       return 0;
+}
+
+static int imx_pd_bind(struct device *dev, struct device *master, void *data)
+{
+       struct drm_device *drm = data;
+       struct device_node *np = dev->of_node;
+       struct device_node *panel_node;
+       const u8 *edidp;
+       struct imx_parallel_display *imxpd;
+       int ret;
+       const char *fmt;
+
+       imxpd = devm_kzalloc(dev, sizeof(*imxpd), GFP_KERNEL);
+       if (!imxpd)
+               return -ENOMEM;
+
+       edidp = of_get_property(np, "edid", &imxpd->edid_len);
+       if (edidp)
+               imxpd->edid = kmemdup(edidp, imxpd->edid_len, GFP_KERNEL);
+
+       ret = of_property_read_string(np, "interface-pix-fmt", &fmt);
+       if (!ret) {
+               if (!strcmp(fmt, "rgb24"))
+                       imxpd->interface_pix_fmt = V4L2_PIX_FMT_RGB24;
+               else if (!strcmp(fmt, "rgb565"))
+                       imxpd->interface_pix_fmt = V4L2_PIX_FMT_RGB565;
+               else if (!strcmp(fmt, "bgr666"))
+                       imxpd->interface_pix_fmt = V4L2_PIX_FMT_BGR666;
+               else if (!strcmp(fmt, "lvds666"))
+                       imxpd->interface_pix_fmt =
+                                       v4l2_fourcc('L', 'V', 'D', '6');
+       }
+
+       panel_node = of_parse_phandle(np, "fsl,panel", 0);
+       if (panel_node)
+               imxpd->panel = of_drm_find_panel(panel_node);
+
+       imxpd->dev = dev;
+
+       ret = imx_pd_register(drm, imxpd);
+       if (ret)
+               return ret;
+
+       dev_set_drvdata(dev, imxpd);
+
+       return 0;
+}
+
+static void imx_pd_unbind(struct device *dev, struct device *master,
+       void *data)
+{
+       struct imx_parallel_display *imxpd = dev_get_drvdata(dev);
+
+       imxpd->encoder.funcs->destroy(&imxpd->encoder);
+       imxpd->connector.funcs->destroy(&imxpd->connector);
+}
+
+static const struct component_ops imx_pd_ops = {
+       .bind   = imx_pd_bind,
+       .unbind = imx_pd_unbind,
+};
+
+static int imx_pd_probe(struct platform_device *pdev)
+{
+       return component_add(&pdev->dev, &imx_pd_ops);
+}
+
+static int imx_pd_remove(struct platform_device *pdev)
+{
+       component_del(&pdev->dev, &imx_pd_ops);
+       return 0;
+}
+
+static const struct of_device_id imx_pd_dt_ids[] = {
+       { .compatible = "fsl,imx-parallel-display", },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_pd_dt_ids);
+
+static struct platform_driver imx_pd_driver = {
+       .probe          = imx_pd_probe,
+       .remove         = imx_pd_remove,
+       .driver         = {
+               .of_match_table = imx_pd_dt_ids,
+               .name   = "imx-parallel-display",
+               .owner  = THIS_MODULE,
+       },
+};
+
+module_platform_driver(imx_pd_driver);
+
+MODULE_DESCRIPTION("i.MX parallel display driver");
+MODULE_AUTHOR("Sascha Hauer, Pengutronix");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-parallel-display");
index 4690ae9..9425728 100644 (file)
@@ -86,8 +86,6 @@ source "drivers/staging/gdm72xx/Kconfig"
 
 source "drivers/staging/gdm724x/Kconfig"
 
-source "drivers/staging/imx-drm/Kconfig"
-
 source "drivers/staging/fwserial/Kconfig"
 
 source "drivers/staging/goldfish/Kconfig"
index c780a0e..bc233dd 100644 (file)
@@ -36,7 +36,6 @@ obj-$(CONFIG_STAGING_BOARD)   += board/
 obj-$(CONFIG_USB_WPAN_HCD)     += ozwpan/
 obj-$(CONFIG_WIMAX_GDM72XX)    += gdm72xx/
 obj-$(CONFIG_LTE_GDM724X)      += gdm724x/
-obj-$(CONFIG_DRM_IMX)          += imx-drm/
 obj-$(CONFIG_FIREWIRE_SERIAL)  += fwserial/
 obj-$(CONFIG_GOLDFISH)         += goldfish/
 obj-$(CONFIG_LUSTRE_FS)                += lustre/
diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/staging/imx-drm/Kconfig
deleted file mode 100644 (file)
index 82fb758..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-config DRM_IMX
-       tristate "DRM Support for Freescale i.MX"
-       select DRM_KMS_HELPER
-       select DRM_KMS_FB_HELPER
-       select VIDEOMODE_HELPERS
-       select DRM_GEM_CMA_HELPER
-       select DRM_KMS_CMA_HELPER
-       depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM)
-       help
-         enable i.MX graphics support
-
-config DRM_IMX_FB_HELPER
-       tristate "provide legacy framebuffer /dev/fb0"
-       select DRM_KMS_CMA_HELPER
-       depends on DRM_IMX
-       help
-         The DRM framework can provide a legacy /dev/fb0 framebuffer
-         for your device. This is necessary to get a framebuffer console
-         and also for applications using the legacy framebuffer API
-
-config DRM_IMX_PARALLEL_DISPLAY
-       tristate "Support for parallel displays"
-       select DRM_PANEL
-       depends on DRM_IMX
-       select VIDEOMODE_HELPERS
-
-config DRM_IMX_TVE
-       tristate "Support for TV and VGA displays"
-       depends on DRM_IMX
-       select REGMAP_MMIO
-       help
-         Choose this to enable the internal Television Encoder (TVe)
-         found on i.MX53 processors.
-
-config DRM_IMX_LDB
-       tristate "Support for LVDS displays"
-       depends on DRM_IMX && MFD_SYSCON
-       help
-         Choose this to enable the internal LVDS Display Bridge (LDB)
-         found on i.MX53 and i.MX6 processors.
-
-config DRM_IMX_IPUV3
-       tristate "DRM Support for i.MX IPUv3"
-       depends on DRM_IMX
-       depends on IMX_IPUV3_CORE
-       help
-         Choose this if you have a i.MX5 or i.MX6 processor.
-
-config DRM_IMX_HDMI
-       tristate "Freescale i.MX DRM HDMI"
-       depends on DRM_IMX
-       help
-         Choose this if you want to use HDMI on i.MX6.
diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile
deleted file mode 100644 (file)
index 582c438..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-
-imxdrm-objs := imx-drm-core.o
-
-obj-$(CONFIG_DRM_IMX) += imxdrm.o
-
-obj-$(CONFIG_DRM_IMX_PARALLEL_DISPLAY) += parallel-display.o
-obj-$(CONFIG_DRM_IMX_TVE) += imx-tve.o
-obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o
-
-imx-ipuv3-crtc-objs  := ipuv3-crtc.o ipuv3-plane.o
-obj-$(CONFIG_DRM_IMX_IPUV3)    += imx-ipuv3-crtc.o
-obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o
diff --git a/drivers/staging/imx-drm/TODO b/drivers/staging/imx-drm/TODO
deleted file mode 100644 (file)
index 29636fb..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-TODO:
-- get DRM Maintainer review for this code
-- decide where to put the base driver. It is not specific to a subsystem
-  and would be used by DRM/KMS and media/V4L2
-
-Missing features (not necessarily for moving out of staging):
-
-- Add support for IC (Image converter)
-- Add support for CSI (CMOS Sensor interface)
-- Add support for VDIC (Video Deinterlacer)
-
-Many work-in-progress patches for the above features exist. Contact
-Sascha Hauer <kernel@pengutronix.de> if you are interested in working
-on a specific feature.
-
-Please send any patches to Greg Kroah-Hartman <gregkh@linuxfoundation.org> and
-Sascha Hauer <kernel@pengutronix.de>
diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c
deleted file mode 100644 (file)
index 2f80072..0000000
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * Freescale i.MX drm driver
- *
- * Copyright (C) 2011 Sascha Hauer, Pengutronix
- *
- * 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.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-#include <linux/component.h>
-#include <linux/device.h>
-#include <linux/fb.h>
-#include <linux/module.h>
-#include <linux/of_graph.h>
-#include <linux/platform_device.h>
-#include <drm/drmP.h>
-#include <drm/drm_fb_helper.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_gem_cma_helper.h>
-#include <drm/drm_fb_cma_helper.h>
-#include <drm/drm_plane_helper.h>
-
-#include "imx-drm.h"
-
-#define MAX_CRTC       4
-
-struct imx_drm_crtc;
-
-struct imx_drm_component {
-       struct device_node *of_node;
-       struct list_head list;
-};
-
-struct imx_drm_device {
-       struct drm_device                       *drm;
-       struct imx_drm_crtc                     *crtc[MAX_CRTC];
-       int                                     pipes;
-       struct drm_fbdev_cma                    *fbhelper;
-};
-
-struct imx_drm_crtc {
-       struct drm_crtc                         *crtc;
-       int                                     pipe;
-       struct imx_drm_crtc_helper_funcs        imx_drm_helper_funcs;
-       struct device_node                      *port;
-};
-
-static int legacyfb_depth = 16;
-module_param(legacyfb_depth, int, 0444);
-
-int imx_drm_crtc_id(struct imx_drm_crtc *crtc)
-{
-       return crtc->pipe;
-}
-EXPORT_SYMBOL_GPL(imx_drm_crtc_id);
-
-static void imx_drm_driver_lastclose(struct drm_device *drm)
-{
-#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER)
-       struct imx_drm_device *imxdrm = drm->dev_private;
-
-       if (imxdrm->fbhelper)
-               drm_fbdev_cma_restore_mode(imxdrm->fbhelper);
-#endif
-}
-
-static int imx_drm_driver_unload(struct drm_device *drm)
-{
-#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER)
-       struct imx_drm_device *imxdrm = drm->dev_private;
-#endif
-
-       drm_kms_helper_poll_fini(drm);
-
-#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER)
-       if (imxdrm->fbhelper)
-               drm_fbdev_cma_fini(imxdrm->fbhelper);
-#endif
-
-       component_unbind_all(drm->dev, drm);
-
-       drm_vblank_cleanup(drm);
-       drm_mode_config_cleanup(drm);
-
-       platform_set_drvdata(drm->platformdev, NULL);
-
-       return 0;
-}
-
-static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc)
-{
-       struct imx_drm_device *imxdrm = crtc->dev->dev_private;
-       unsigned i;
-
-       for (i = 0; i < MAX_CRTC; i++)
-               if (imxdrm->crtc[i] && imxdrm->crtc[i]->crtc == crtc)
-                       return imxdrm->crtc[i];
-
-       return NULL;
-}
-
-int imx_drm_panel_format_pins(struct drm_encoder *encoder,
-               u32 interface_pix_fmt, int hsync_pin, int vsync_pin)
-{
-       struct imx_drm_crtc_helper_funcs *helper;
-       struct imx_drm_crtc *imx_crtc;
-
-       imx_crtc = imx_drm_find_crtc(encoder->crtc);
-       if (!imx_crtc)
-               return -EINVAL;
-
-       helper = &imx_crtc->imx_drm_helper_funcs;
-       if (helper->set_interface_pix_fmt)
-               return helper->set_interface_pix_fmt(encoder->crtc,
-                               encoder->encoder_type, interface_pix_fmt,
-                               hsync_pin, vsync_pin);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(imx_drm_panel_format_pins);
-
-int imx_drm_panel_format(struct drm_encoder *encoder, u32 interface_pix_fmt)
-{
-       return imx_drm_panel_format_pins(encoder, interface_pix_fmt, 2, 3);
-}
-EXPORT_SYMBOL_GPL(imx_drm_panel_format);
-
-int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc)
-{
-       return drm_vblank_get(imx_drm_crtc->crtc->dev, imx_drm_crtc->pipe);
-}
-EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_get);
-
-void imx_drm_crtc_vblank_put(struct imx_drm_crtc *imx_drm_crtc)
-{
-       drm_vblank_put(imx_drm_crtc->crtc->dev, imx_drm_crtc->pipe);
-}
-EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_put);
-
-void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc)
-{
-       drm_handle_vblank(imx_drm_crtc->crtc->dev, imx_drm_crtc->pipe);
-}
-EXPORT_SYMBOL_GPL(imx_drm_handle_vblank);
-
-static int imx_drm_enable_vblank(struct drm_device *drm, int crtc)
-{
-       struct imx_drm_device *imxdrm = drm->dev_private;
-       struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[crtc];
-       int ret;
-
-       if (!imx_drm_crtc)
-               return -EINVAL;
-
-       if (!imx_drm_crtc->imx_drm_helper_funcs.enable_vblank)
-               return -ENOSYS;
-
-       ret = imx_drm_crtc->imx_drm_helper_funcs.enable_vblank(
-                       imx_drm_crtc->crtc);
-
-       return ret;
-}
-
-static void imx_drm_disable_vblank(struct drm_device *drm, int crtc)
-{
-       struct imx_drm_device *imxdrm = drm->dev_private;
-       struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[crtc];
-
-       if (!imx_drm_crtc)
-               return;
-
-       if (!imx_drm_crtc->imx_drm_helper_funcs.disable_vblank)
-               return;
-
-       imx_drm_crtc->imx_drm_helper_funcs.disable_vblank(imx_drm_crtc->crtc);
-}
-
-static void imx_drm_driver_preclose(struct drm_device *drm,
-               struct drm_file *file)
-{
-       int i;
-
-       if (!file->is_master)
-               return;
-
-       for (i = 0; i < MAX_CRTC; i++)
-               imx_drm_disable_vblank(drm, i);
-}
-
-static const struct file_operations imx_drm_driver_fops = {
-       .owner = THIS_MODULE,
-       .open = drm_open,
-       .release = drm_release,
-       .unlocked_ioctl = drm_ioctl,
-       .mmap = drm_gem_cma_mmap,
-       .poll = drm_poll,
-       .read = drm_read,
-       .llseek = noop_llseek,
-};
-
-void imx_drm_connector_destroy(struct drm_connector *connector)
-{
-       drm_connector_unregister(connector);
-       drm_connector_cleanup(connector);
-}
-EXPORT_SYMBOL_GPL(imx_drm_connector_destroy);
-
-void imx_drm_encoder_destroy(struct drm_encoder *encoder)
-{
-       drm_encoder_cleanup(encoder);
-}
-EXPORT_SYMBOL_GPL(imx_drm_encoder_destroy);
-
-static void imx_drm_output_poll_changed(struct drm_device *drm)
-{
-#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER)
-       struct imx_drm_device *imxdrm = drm->dev_private;
-
-       drm_fbdev_cma_hotplug_event(imxdrm->fbhelper);
-#endif
-}
-
-static struct drm_mode_config_funcs imx_drm_mode_config_funcs = {
-       .fb_create = drm_fb_cma_create,
-       .output_poll_changed = imx_drm_output_poll_changed,
-};
-
-/*
- * Main DRM initialisation. This binds, initialises and registers
- * with DRM the subcomponents of the driver.
- */
-static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
-{
-       struct imx_drm_device *imxdrm;
-       struct drm_connector *connector;
-       int ret;
-
-       imxdrm = devm_kzalloc(drm->dev, sizeof(*imxdrm), GFP_KERNEL);
-       if (!imxdrm)
-               return -ENOMEM;
-
-       imxdrm->drm = drm;
-
-       drm->dev_private = imxdrm;
-
-       /*
-        * enable drm irq mode.
-        * - with irq_enabled = true, we can use the vblank feature.
-        *
-        * P.S. note that we wouldn't use drm irq handler but
-        *      just specific driver own one instead because
-        *      drm framework supports only one irq handler and
-        *      drivers can well take care of their interrupts
-        */
-       drm->irq_enabled = true;
-
-       /*
-        * set max width and height as default value(4096x4096).
-        * this value would be used to check framebuffer size limitation
-        * at drm_mode_addfb().
-        */
-       drm->mode_config.min_width = 64;
-       drm->mode_config.min_height = 64;
-       drm->mode_config.max_width = 4096;
-       drm->mode_config.max_height = 4096;
-       drm->mode_config.funcs = &imx_drm_mode_config_funcs;
-
-       drm_mode_config_init(drm);
-
-       ret = drm_vblank_init(drm, MAX_CRTC);
-       if (ret)
-               goto err_kms;
-
-       /*
-        * with vblank_disable_allowed = true, vblank interrupt will be
-        * disabled by drm timer once a current process gives up ownership
-        * of vblank event. (after drm_vblank_put function is called)
-        */
-       drm->vblank_disable_allowed = true;
-
-       platform_set_drvdata(drm->platformdev, drm);
-
-       /* Now try and bind all our sub-components */
-       ret = component_bind_all(drm->dev, drm);
-       if (ret)
-               goto err_vblank;
-
-       /*
-        * All components are now added, we can publish the connector sysfs
-        * entries to userspace.  This will generate hotplug events and so
-        * userspace will expect to be able to access DRM at this point.
-        */
-       list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
-               ret = drm_connector_register(connector);
-               if (ret) {
-                       dev_err(drm->dev,
-                               "[CONNECTOR:%d:%s] drm_connector_register failed: %d\n",
-                               connector->base.id,
-                               connector->name, ret);
-                       goto err_unbind;
-               }
-       }
-
-       /*
-        * All components are now initialised, so setup the fb helper.
-        * The fb helper takes copies of key hardware information, so the
-        * crtcs/connectors/encoders must not change after this point.
-        */
-#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER)
-       if (legacyfb_depth != 16 && legacyfb_depth != 32) {
-               dev_warn(drm->dev, "Invalid legacyfb_depth.  Defaulting to 16bpp\n");
-               legacyfb_depth = 16;
-       }
-       imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth,
-                               drm->mode_config.num_crtc, MAX_CRTC);
-       if (IS_ERR(imxdrm->fbhelper)) {
-               ret = PTR_ERR(imxdrm->fbhelper);
-               imxdrm->fbhelper = NULL;
-               goto err_unbind;
-       }
-#endif
-
-       drm_kms_helper_poll_init(drm);
-
-       return 0;
-
-err_unbind:
-       component_unbind_all(drm->dev, drm);
-err_vblank:
-       drm_vblank_cleanup(drm);
-err_kms:
-       drm_mode_config_cleanup(drm);
-
-       return ret;
-}
-
-/*
- * imx_drm_add_crtc - add a new crtc
- */
-int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
-               struct imx_drm_crtc **new_crtc,
-               const struct imx_drm_crtc_helper_funcs *imx_drm_helper_funcs,
-               struct device_node *port)
-{
-       struct imx_drm_device *imxdrm = drm->dev_private;
-       struct imx_drm_crtc *imx_drm_crtc;
-       int ret;
-
-       /*
-        * The vblank arrays are dimensioned by MAX_CRTC - we can't
-        * pass IDs greater than this to those functions.
-        */
-       if (imxdrm->pipes >= MAX_CRTC)
-               return -EINVAL;
-
-       if (imxdrm->drm->open_count)
-               return -EBUSY;
-
-       imx_drm_crtc = kzalloc(sizeof(*imx_drm_crtc), GFP_KERNEL);
-       if (!imx_drm_crtc)
-               return -ENOMEM;
-
-       imx_drm_crtc->imx_drm_helper_funcs = *imx_drm_helper_funcs;
-       imx_drm_crtc->pipe = imxdrm->pipes++;
-       imx_drm_crtc->port = port;
-       imx_drm_crtc->crtc = crtc;
-
-       imxdrm->crtc[imx_drm_crtc->pipe] = imx_drm_crtc;
-
-       *new_crtc = imx_drm_crtc;
-
-       ret = drm_mode_crtc_set_gamma_size(imx_drm_crtc->crtc, 256);
-       if (ret)
-               goto err_register;
-
-       drm_crtc_helper_add(crtc,
-                       imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs);
-
-       drm_crtc_init(drm, crtc,
-                       imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs);
-
-       return 0;
-
-err_register:
-       imxdrm->crtc[imx_drm_crtc->pipe] = NULL;
-       kfree(imx_drm_crtc);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(imx_drm_add_crtc);
-
-/*
- * imx_drm_remove_crtc - remove a crtc
- */
-int imx_drm_remove_crtc(struct imx_drm_crtc *imx_drm_crtc)
-{
-       struct imx_drm_device *imxdrm = imx_drm_crtc->crtc->dev->dev_private;
-
-       drm_crtc_cleanup(imx_drm_crtc->crtc);
-
-       imxdrm->crtc[imx_drm_crtc->pipe] = NULL;
-
-       kfree(imx_drm_crtc);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(imx_drm_remove_crtc);
-
-/*
- * Find the DRM CRTC possible mask for the connected endpoint.
- *
- * The encoder possible masks are defined by their position in the
- * mode_config crtc_list.  This means that CRTCs must not be added
- * or removed once the DRM device has been fully initialised.
- */
-static uint32_t imx_drm_find_crtc_mask(struct imx_drm_device *imxdrm,
-       struct device_node *endpoint)
-{
-       struct device_node *port;
-       unsigned i;
-
-       port = of_graph_get_remote_port(endpoint);
-       if (!port)
-               return 0;
-       of_node_put(port);
-
-       for (i = 0; i < MAX_CRTC; i++) {
-               struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[i];
-
-               if (imx_drm_crtc && imx_drm_crtc->port == port)
-                       return drm_crtc_mask(imx_drm_crtc->crtc);
-       }
-
-       return 0;
-}
-
-static struct device_node *imx_drm_of_get_next_endpoint(
-               const struct device_node *parent, struct device_node *prev)
-{
-       struct device_node *node = of_graph_get_next_endpoint(parent, prev);
-
-       of_node_put(prev);
-       return node;
-}
-
-int imx_drm_encoder_parse_of(struct drm_device *drm,
-       struct drm_encoder *encoder, struct device_node *np)
-{
-       struct imx_drm_device *imxdrm = drm->dev_private;
-       struct device_node *ep = NULL;
-       uint32_t crtc_mask = 0;
-       int i;
-
-       for (i = 0; ; i++) {
-               u32 mask;
-
-               ep = imx_drm_of_get_next_endpoint(np, ep);
-               if (!ep)
-                       break;
-
-               mask = imx_drm_find_crtc_mask(imxdrm, ep);
-
-               /*
-                * If we failed to find the CRTC(s) which this encoder is
-                * supposed to be connected to, it's because the CRTC has
-                * not been registered yet.  Defer probing, and hope that
-                * the required CRTC is added later.
-                */
-               if (mask == 0)
-                       return -EPROBE_DEFER;
-
-               crtc_mask |= mask;
-       }
-
-       of_node_put(ep);
-       if (i == 0)
-               return -ENOENT;
-
-       encoder->possible_crtcs = crtc_mask;
-
-       /* FIXME: this is the mask of outputs which can clone this output. */
-       encoder->possible_clones = ~0;
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(imx_drm_encoder_parse_of);
-
-/*
- * @node: device tree node containing encoder input ports
- * @encoder: drm_encoder
- */
-int imx_drm_encoder_get_mux_id(struct device_node *node,
-                              struct drm_encoder *encoder)
-{
-       struct imx_drm_crtc *imx_crtc = imx_drm_find_crtc(encoder->crtc);
-       struct device_node *ep = NULL;
-       struct of_endpoint endpoint;
-       struct device_node *port;
-       int ret;
-
-       if (!node || !imx_crtc)
-               return -EINVAL;
-
-       do {
-               ep = imx_drm_of_get_next_endpoint(node, ep);
-               if (!ep)
-                       break;
-
-               port = of_graph_get_remote_port(ep);
-               of_node_put(port);
-               if (port == imx_crtc->port) {
-                       ret = of_graph_parse_endpoint(ep, &endpoint);
-                       return ret ? ret : endpoint.port;
-               }
-       } while (ep);
-
-       return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(imx_drm_encoder_get_mux_id);
-
-static const struct drm_ioctl_desc imx_drm_ioctls[] = {
-       /* none so far */
-};
-
-static struct drm_driver imx_drm_driver = {
-       .driver_features        = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
-       .load                   = imx_drm_driver_load,
-       .unload                 = imx_drm_driver_unload,
-       .lastclose              = imx_drm_driver_lastclose,
-       .preclose               = imx_drm_driver_preclose,
-       .set_busid              = drm_platform_set_busid,
-       .gem_free_object        = drm_gem_cma_free_object,
-       .gem_vm_ops             = &drm_gem_cma_vm_ops,
-       .dumb_create            = drm_gem_cma_dumb_create,
-       .dumb_map_offset        = drm_gem_cma_dumb_map_offset,
-       .dumb_destroy           = drm_gem_dumb_destroy,
-
-       .prime_handle_to_fd     = drm_gem_prime_handle_to_fd,
-       .prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
-       .gem_prime_import       = drm_gem_prime_import,
-       .gem_prime_export       = drm_gem_prime_export,
-       .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
-       .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
-       .gem_prime_vmap         = drm_gem_cma_prime_vmap,
-       .gem_prime_vunmap       = drm_gem_cma_prime_vunmap,
-       .gem_prime_mmap         = drm_gem_cma_prime_mmap,
-       .get_vblank_counter     = drm_vblank_count,
-       .enable_vblank          = imx_drm_enable_vblank,
-       .disable_vblank         = imx_drm_disable_vblank,
-       .ioctls                 = imx_drm_ioctls,
-       .num_ioctls             = ARRAY_SIZE(imx_drm_ioctls),
-       .fops                   = &imx_drm_driver_fops,
-       .name                   = "imx-drm",
-       .desc                   = "i.MX DRM graphics",
-       .date                   = "20120507",
-       .major                  = 1,
-       .minor                  = 0,
-       .patchlevel             = 0,
-};
-
-static int compare_of(struct device *dev, void *data)
-{
-       struct device_node *np = data;
-
-       /* Special case for LDB, one device for two channels */
-       if (of_node_cmp(np->name, "lvds-channel") == 0) {
-               np = of_get_parent(np);
-               of_node_put(np);
-       }
-
-       return dev->of_node == np;
-}
-
-static int imx_drm_bind(struct device *dev)
-{
-       return drm_platform_init(&imx_drm_driver, to_platform_device(dev));
-}
-
-static void imx_drm_unbind(struct device *dev)
-{
-       drm_put_dev(dev_get_drvdata(dev));
-}
-
-static const struct component_master_ops imx_drm_ops = {
-       .bind = imx_drm_bind,
-       .unbind = imx_drm_unbind,
-};
-
-static int imx_drm_platform_probe(struct platform_device *pdev)
-{
-       struct device_node *ep, *port, *remote;
-       struct component_match *match = NULL;
-       int ret;
-       int i;
-
-       /*
-        * Bind the IPU display interface ports first, so that
-        * imx_drm_encoder_parse_of called from encoder .bind callbacks
-        * works as expected.
-        */
-       for (i = 0; ; i++) {
-               port = of_parse_phandle(pdev->dev.of_node, "ports", i);
-               if (!port)
-                       break;
-
-               component_match_add(&pdev->dev, &match, compare_of, port);
-       }
-
-       if (i == 0) {
-               dev_err(&pdev->dev, "missing 'ports' property\n");
-               return -ENODEV;
-       }
-
-       /* Then bind all encoders */
-       for (i = 0; ; i++) {
-               port = of_parse_phandle(pdev->dev.of_node, "ports", i);
-               if (!port)
-                       break;
-
-               for_each_child_of_node(port, ep) {
-                       remote = of_graph_get_remote_port_parent(ep);
-                       if (!remote || !of_device_is_available(remote)) {
-                               of_node_put(remote);
-                               continue;
-                       } else if (!of_device_is_available(remote->parent)) {
-                               dev_warn(&pdev->dev, "parent device of %s is not available\n",
-                                        remote->full_name);
-                               of_node_put(remote);
-                               continue;
-                       }
-
-                       component_match_add(&pdev->dev, &match, compare_of, remote);
-                       of_node_put(remote);
-               }
-               of_node_put(port);
-       }
-
-       ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
-       if (ret)
-               return ret;
-
-       return component_master_add_with_match(&pdev->dev, &imx_drm_ops, match);
-}
-
-static int imx_drm_platform_remove(struct platform_device *pdev)
-{
-       component_master_del(&pdev->dev, &imx_drm_ops);
-       return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int imx_drm_suspend(struct device *dev)
-{
-       struct drm_device *drm_dev = dev_get_drvdata(dev);
-
-       /* The drm_dev is NULL before .load hook is called */
-       if (drm_dev == NULL)
-               return 0;
-
-       drm_kms_helper_poll_disable(drm_dev);
-
-       return 0;
-}
-
-static int imx_drm_resume(struct device *dev)
-{
-       struct drm_device *drm_dev = dev_get_drvdata(dev);
-
-       if (drm_dev == NULL)
-               return 0;
-
-       drm_helper_resume_force_mode(drm_dev);
-       drm_kms_helper_poll_enable(drm_dev);
-
-       return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(imx_drm_pm_ops, imx_drm_suspend, imx_drm_resume);
-
-static const struct of_device_id imx_drm_dt_ids[] = {
-       { .compatible = "fsl,imx-display-subsystem", },
-       { /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, imx_drm_dt_ids);
-
-static struct platform_driver imx_drm_pdrv = {
-       .probe          = imx_drm_platform_probe,
-       .remove         = imx_drm_platform_remove,
-       .driver         = {
-               .owner  = THIS_MODULE,
-               .name   = "imx-drm",
-               .pm     = &imx_drm_pm_ops,
-               .of_match_table = imx_drm_dt_ids,
-       },
-};
-module_platform_driver(imx_drm_pdrv);
-
-MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
-MODULE_DESCRIPTION("i.MX drm driver core");
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h
deleted file mode 100644 (file)
index 7453ae0..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef _IMX_DRM_H_
-#define _IMX_DRM_H_
-
-struct device_node;
-struct drm_crtc;
-struct drm_connector;
-struct drm_device;
-struct drm_display_mode;
-struct drm_encoder;
-struct drm_fbdev_cma;
-struct drm_framebuffer;
-struct imx_drm_crtc;
-struct platform_device;
-
-int imx_drm_crtc_id(struct imx_drm_crtc *crtc);
-
-struct imx_drm_crtc_helper_funcs {
-       int (*enable_vblank)(struct drm_crtc *crtc);
-       void (*disable_vblank)(struct drm_crtc *crtc);
-       int (*set_interface_pix_fmt)(struct drm_crtc *crtc, u32 encoder_type,
-                       u32 pix_fmt, int hsync_pin, int vsync_pin);
-       const struct drm_crtc_helper_funcs *crtc_helper_funcs;
-       const struct drm_crtc_funcs *crtc_funcs;
-};
-
-int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc,
-               struct imx_drm_crtc **new_crtc,
-               const struct imx_drm_crtc_helper_funcs *imx_helper_funcs,
-               struct device_node *port);
-int imx_drm_remove_crtc(struct imx_drm_crtc *);
-int imx_drm_init_drm(struct platform_device *pdev,
-               int preferred_bpp);
-int imx_drm_exit_drm(void);
-
-int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc);
-void imx_drm_crtc_vblank_put(struct imx_drm_crtc *imx_drm_crtc);
-void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc);
-
-void imx_drm_mode_config_init(struct drm_device *drm);
-
-struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb);
-
-int imx_drm_panel_format_pins(struct drm_encoder *encoder,
-               u32 interface_pix_fmt, int hsync_pin, int vsync_pin);
-int imx_drm_panel_format(struct drm_encoder *encoder,
-               u32 interface_pix_fmt);
-
-int imx_drm_encoder_get_mux_id(struct device_node *node,
-               struct drm_encoder *encoder);
-int imx_drm_encoder_parse_of(struct drm_device *drm,
-       struct drm_encoder *encoder, struct device_node *np);
-
-void imx_drm_connector_destroy(struct drm_connector *connector);
-void imx_drm_encoder_destroy(struct drm_encoder *encoder);
-
-#endif /* _IMX_DRM_H_ */
diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c
deleted file mode 100644 (file)
index aaec6b2..0000000
+++ /dev/null
@@ -1,1767 +0,0 @@
-/*
- * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
- *
- * 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.
- *
- * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
- * for SLISHDMI13T and SLIPHDMIT IP cores
- *
- * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
- */
-
-#include <linux/component.h>
-#include <linux/irq.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/hdmi.h>
-#include <linux/regmap.h>
-#include <linux/mfd/syscon.h>
-#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
-#include <linux/of_device.h>
-
-#include <drm/drmP.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_edid.h>
-#include <drm/drm_encoder_slave.h>
-#include <video/imx-ipu-v3.h>
-
-#include "imx-hdmi.h"
-#include "imx-drm.h"
-
-#define HDMI_EDID_LEN          512
-
-#define RGB                    0
-#define YCBCR444               1
-#define YCBCR422_16BITS                2
-#define YCBCR422_8BITS         3
-#define XVYCC444               4
-
-enum hdmi_datamap {
-       RGB444_8B = 0x01,
-       RGB444_10B = 0x03,
-       RGB444_12B = 0x05,
-       RGB444_16B = 0x07,
-       YCbCr444_8B = 0x09,
-       YCbCr444_10B = 0x0B,
-       YCbCr444_12B = 0x0D,
-       YCbCr444_16B = 0x0F,
-       YCbCr422_8B = 0x16,
-       YCbCr422_10B = 0x14,
-       YCbCr422_12B = 0x12,
-};
-
-enum imx_hdmi_devtype {
-       IMX6Q_HDMI,
-       IMX6DL_HDMI,
-};
-
-static const u16 csc_coeff_default[3][4] = {
-       { 0x2000, 0x0000, 0x0000, 0x0000 },
-       { 0x0000, 0x2000, 0x0000, 0x0000 },
-       { 0x0000, 0x0000, 0x2000, 0x0000 }
-};
-
-static const u16 csc_coeff_rgb_out_eitu601[3][4] = {
-       { 0x2000, 0x6926, 0x74fd, 0x010e },
-       { 0x2000, 0x2cdd, 0x0000, 0x7e9a },
-       { 0x2000, 0x0000, 0x38b4, 0x7e3b }
-};
-
-static const u16 csc_coeff_rgb_out_eitu709[3][4] = {
-       { 0x2000, 0x7106, 0x7a02, 0x00a7 },
-       { 0x2000, 0x3264, 0x0000, 0x7e6d },
-       { 0x2000, 0x0000, 0x3b61, 0x7e25 }
-};
-
-static const u16 csc_coeff_rgb_in_eitu601[3][4] = {
-       { 0x2591, 0x1322, 0x074b, 0x0000 },
-       { 0x6535, 0x2000, 0x7acc, 0x0200 },
-       { 0x6acd, 0x7534, 0x2000, 0x0200 }
-};
-
-static const u16 csc_coeff_rgb_in_eitu709[3][4] = {
-       { 0x2dc5, 0x0d9b, 0x049e, 0x0000 },
-       { 0x62f0, 0x2000, 0x7d11, 0x0200 },
-       { 0x6756, 0x78ab, 0x2000, 0x0200 }
-};
-
-struct hdmi_vmode {
-       bool mdvi;
-       bool mhsyncpolarity;
-       bool mvsyncpolarity;
-       bool minterlaced;
-       bool mdataenablepolarity;
-
-       unsigned int mpixelclock;
-       unsigned int mpixelrepetitioninput;
-       unsigned int mpixelrepetitionoutput;
-};
-
-struct hdmi_data_info {
-       unsigned int enc_in_format;
-       unsigned int enc_out_format;
-       unsigned int enc_color_depth;
-       unsigned int colorimetry;
-       unsigned int pix_repet_factor;
-       unsigned int hdcp_enable;
-       struct hdmi_vmode video_mode;
-};
-
-struct imx_hdmi {
-       struct drm_connector connector;
-       struct drm_encoder encoder;
-
-       enum imx_hdmi_devtype dev_type;
-       struct device *dev;
-       struct clk *isfr_clk;
-       struct clk *iahb_clk;
-
-       struct hdmi_data_info hdmi_data;
-       int vic;
-
-       u8 edid[HDMI_EDID_LEN];
-       bool cable_plugin;
-
-       bool phy_enabled;
-       struct drm_display_mode previous_mode;
-
-       struct regmap *regmap;
-       struct i2c_adapter *ddc;
-       void __iomem *regs;
-
-       unsigned int sample_rate;
-       int ratio;
-};
-
-static void imx_hdmi_set_ipu_di_mux(struct imx_hdmi *hdmi, int ipu_di)
-{
-       regmap_update_bits(hdmi->regmap, IOMUXC_GPR3,
-                          IMX6Q_GPR3_HDMI_MUX_CTL_MASK,
-                          ipu_di << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT);
-}
-
-static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset)
-{
-       writeb(val, hdmi->regs + offset);
-}
-
-static inline u8 hdmi_readb(struct imx_hdmi *hdmi, int offset)
-{
-       return readb(hdmi->regs + offset);
-}
-
-static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
-{
-       u8 val = hdmi_readb(hdmi, reg) & ~mask;
-
-       val |= data & mask;
-       hdmi_writeb(hdmi, val, reg);
-}
-
-static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg,
-                     u8 shift, u8 mask)
-{
-       hdmi_modb(hdmi, data << shift, mask, reg);
-}
-
-static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi,
-                                        unsigned int value)
-{
-       hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1);
-       hdmi_writeb(hdmi, (value >> 8) & 0xff, HDMI_AUD_N2);
-       hdmi_writeb(hdmi, (value >> 16) & 0x0f, HDMI_AUD_N3);
-
-       /* nshift factor = 0 */
-       hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);
-}
-
-static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts)
-{
-       /* Must be set/cleared first */
-       hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
-
-       hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1);
-       hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
-       hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
-                   HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
-}
-
-static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
-                                  unsigned int ratio)
-{
-       unsigned int n = (128 * freq) / 1000;
-
-       switch (freq) {
-       case 32000:
-               if (pixel_clk == 25170000)
-                       n = (ratio == 150) ? 9152 : 4576;
-               else if (pixel_clk == 27020000)
-                       n = (ratio == 150) ? 8192 : 4096;
-               else if (pixel_clk == 74170000 || pixel_clk == 148350000)
-                       n = 11648;
-               else
-                       n = 4096;
-               break;
-
-       case 44100:
-               if (pixel_clk == 25170000)
-                       n = 7007;
-               else if (pixel_clk == 74170000)
-                       n = 17836;
-               else if (pixel_clk == 148350000)
-                       n = (ratio == 150) ? 17836 : 8918;
-               else
-                       n = 6272;
-               break;
-
-       case 48000:
-               if (pixel_clk == 25170000)
-                       n = (ratio == 150) ? 9152 : 6864;
-               else if (pixel_clk == 27020000)
-                       n = (ratio == 150) ? 8192 : 6144;
-               else if (pixel_clk == 74170000)
-                       n = 11648;
-               else if (pixel_clk == 148350000)
-                       n = (ratio == 150) ? 11648 : 5824;
-               else
-                       n = 6144;
-               break;
-
-       case 88200:
-               n = hdmi_compute_n(44100, pixel_clk, ratio) * 2;
-               break;
-
-       case 96000:
-               n = hdmi_compute_n(48000, pixel_clk, ratio) * 2;
-               break;
-
-       case 176400:
-               n = hdmi_compute_n(44100, pixel_clk, ratio) * 4;
-               break;
-
-       case 192000:
-               n = hdmi_compute_n(48000, pixel_clk, ratio) * 4;
-               break;
-
-       default:
-               break;
-       }
-
-       return n;
-}
-
-static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
-                                    unsigned int ratio)
-{
-       unsigned int cts = 0;
-
-       pr_debug("%s: freq: %d pixel_clk: %ld ratio: %d\n", __func__, freq,
-                pixel_clk, ratio);
-
-       switch (freq) {
-       case 32000:
-               if (pixel_clk == 297000000) {
-                       cts = 222750;
-                       break;
-               }
-       case 48000:
-       case 96000:
-       case 192000:
-               switch (pixel_clk) {
-               case 25200000:
-               case 27000000:
-               case 54000000:
-               case 74250000:
-               case 148500000:
-                       cts = pixel_clk / 1000;
-                       break;
-               case 297000000:
-                       cts = 247500;
-                       break;
-               /*
-                * All other TMDS clocks are not supported by
-                * DWC_hdmi_tx. The TMDS clocks divided or
-                * multiplied by 1,001 coefficients are not
-                * supported.
-                */
-               default:
-                       break;
-               }
-               break;
-       case 44100:
-       case 88200:
-       case 176400:
-               switch (pixel_clk) {
-               case 25200000:
-                       cts = 28000;
-                       break;
-               case 27000000:
-                       cts = 30000;
-                       break;
-               case 54000000:
-                       cts = 60000;
-                       break;
-               case 74250000:
-                       cts = 82500;
-                       break;
-               case 148500000:
-                       cts = 165000;
-                       break;
-               case 297000000:
-                       cts = 247500;
-                       break;
-               default:
-                       break;
-               }
-               break;
-       default:
-               break;
-       }
-       if (ratio == 100)
-               return cts;
-       return (cts * ratio) / 100;
-}
-
-static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi,
-       unsigned long pixel_clk)
-{
-       unsigned int clk_n, clk_cts;
-
-       clk_n = hdmi_compute_n(hdmi->sample_rate, pixel_clk,
-                              hdmi->ratio);
-       clk_cts = hdmi_compute_cts(hdmi->sample_rate, pixel_clk,
-                                  hdmi->ratio);
-
-       if (!clk_cts) {
-               dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n",
-                        __func__, pixel_clk);
-               return;
-       }
-
-       dev_dbg(hdmi->dev, "%s: samplerate=%d  ratio=%d  pixelclk=%lu  N=%d cts=%d\n",
-               __func__, hdmi->sample_rate, hdmi->ratio,
-               pixel_clk, clk_n, clk_cts);
-
-       hdmi_set_clock_regenerator_n(hdmi, clk_n);
-       hdmi_regenerate_cts(hdmi, clk_cts);
-}
-
-static void hdmi_init_clk_regenerator(struct imx_hdmi *hdmi)
-{
-       hdmi_set_clk_regenerator(hdmi, 74250000);
-}
-
-static void hdmi_clk_regenerator_update_pixel_clock(struct imx_hdmi *hdmi)
-{
-       hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock);
-}
-
-/*
- * this submodule is responsible for the video data synchronization.
- * for example, for RGB 4:4:4 input, the data map is defined as
- *                     pin{47~40} <==> R[7:0]
- *                     pin{31~24} <==> G[7:0]
- *                     pin{15~8}  <==> B[7:0]
- */
-static void hdmi_video_sample(struct imx_hdmi *hdmi)
-{
-       int color_format = 0;
-       u8 val;
-
-       if (hdmi->hdmi_data.enc_in_format == RGB) {
-               if (hdmi->hdmi_data.enc_color_depth == 8)
-                       color_format = 0x01;
-               else if (hdmi->hdmi_data.enc_color_depth == 10)
-                       color_format = 0x03;
-               else if (hdmi->hdmi_data.enc_color_depth == 12)
-                       color_format = 0x05;
-               else if (hdmi->hdmi_data.enc_color_depth == 16)
-                       color_format = 0x07;
-               else
-                       return;
-       } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) {
-               if (hdmi->hdmi_data.enc_color_depth == 8)
-                       color_format = 0x09;
-               else if (hdmi->hdmi_data.enc_color_depth == 10)
-                       color_format = 0x0B;
-               else if (hdmi->hdmi_data.enc_color_depth == 12)
-                       color_format = 0x0D;
-               else if (hdmi->hdmi_data.enc_color_depth == 16)
-                       color_format = 0x0F;
-               else
-                       return;
-       } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) {
-               if (hdmi->hdmi_data.enc_color_depth == 8)
-                       color_format = 0x16;
-               else if (hdmi->hdmi_data.enc_color_depth == 10)
-                       color_format = 0x14;
-               else if (hdmi->hdmi_data.enc_color_depth == 12)
-                       color_format = 0x12;
-               else
-                       return;
-       }
-
-       val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
-               ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
-               HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
-       hdmi_writeb(hdmi, val, HDMI_TX_INVID0);
-
-       /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */
-       val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
-               HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
-               HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
-       hdmi_writeb(hdmi, val, HDMI_TX_INSTUFFING);
-       hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA0);
-       hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA1);
-       hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA0);
-       hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA1);
-       hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA0);
-       hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1);
-}
-
-static int is_color_space_conversion(struct imx_hdmi *hdmi)
-{
-       return hdmi->hdmi_data.enc_in_format != hdmi->hdmi_data.enc_out_format;
-}
-
-static int is_color_space_decimation(struct imx_hdmi *hdmi)
-{
-       if (hdmi->hdmi_data.enc_out_format != YCBCR422_8BITS)
-               return 0;
-       if (hdmi->hdmi_data.enc_in_format == RGB ||
-           hdmi->hdmi_data.enc_in_format == YCBCR444)
-               return 1;
-       return 0;
-}
-
-static int is_color_space_interpolation(struct imx_hdmi *hdmi)
-{
-       if (hdmi->hdmi_data.enc_in_format != YCBCR422_8BITS)
-               return 0;
-       if (hdmi->hdmi_data.enc_out_format == RGB ||
-           hdmi->hdmi_data.enc_out_format == YCBCR444)
-               return 1;
-       return 0;
-}
-
-static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
-{
-       const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
-       unsigned i;
-       u32 csc_scale = 1;
-
-       if (is_color_space_conversion(hdmi)) {
-               if (hdmi->hdmi_data.enc_out_format == RGB) {
-                       if (hdmi->hdmi_data.colorimetry ==
-                                       HDMI_COLORIMETRY_ITU_601)
-                               csc_coeff = &csc_coeff_rgb_out_eitu601;
-                       else
-                               csc_coeff = &csc_coeff_rgb_out_eitu709;
-               } else if (hdmi->hdmi_data.enc_in_format == RGB) {
-                       if (hdmi->hdmi_data.colorimetry ==
-                                       HDMI_COLORIMETRY_ITU_601)
-                               csc_coeff = &csc_coeff_rgb_in_eitu601;
-                       else
-                               csc_coeff = &csc_coeff_rgb_in_eitu709;
-                       csc_scale = 0;
-               }
-       }
-
-       /* The CSC registers are sequential, alternating MSB then LSB */
-       for (i = 0; i < ARRAY_SIZE(csc_coeff_default[0]); i++) {
-               u16 coeff_a = (*csc_coeff)[0][i];
-               u16 coeff_b = (*csc_coeff)[1][i];
-               u16 coeff_c = (*csc_coeff)[2][i];
-
-               hdmi_writeb(hdmi, coeff_a & 0xff,
-                       HDMI_CSC_COEF_A1_LSB + i * 2);
-               hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2);
-               hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2);
-               hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2);
-               hdmi_writeb(hdmi, coeff_c & 0xff,
-                       HDMI_CSC_COEF_C1_LSB + i * 2);
-               hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2);
-       }
-
-       hdmi_modb(hdmi, csc_scale, HDMI_CSC_SCALE_CSCSCALE_MASK,
-                 HDMI_CSC_SCALE);
-}
-
-static void hdmi_video_csc(struct imx_hdmi *hdmi)
-{
-       int color_depth = 0;
-       int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
-       int decimation = 0;
-
-       /* YCC422 interpolation to 444 mode */
-       if (is_color_space_interpolation(hdmi))
-               interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1;
-       else if (is_color_space_decimation(hdmi))
-               decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3;
-
-       if (hdmi->hdmi_data.enc_color_depth == 8)
-               color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP;
-       else if (hdmi->hdmi_data.enc_color_depth == 10)
-               color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP;
-       else if (hdmi->hdmi_data.enc_color_depth == 12)
-               color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP;
-       else if (hdmi->hdmi_data.enc_color_depth == 16)
-               color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP;
-       else
-               return;
-
-       /* Configure the CSC registers */
-       hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG);
-       hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK,
-                 HDMI_CSC_SCALE);
-
-       imx_hdmi_update_csc_coeffs(hdmi);
-}
-
-/*
- * HDMI video packetizer is used to packetize the data.
- * for example, if input is YCC422 mode or repeater is used,
- * data should be repacked this module can be bypassed.
- */
-static void hdmi_video_packetize(struct imx_hdmi *hdmi)
-{
-       unsigned int color_depth = 0;
-       unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit;
-       unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP;
-       struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
-       u8 val, vp_conf;
-
-       if (hdmi_data->enc_out_format == RGB
-               || hdmi_data->enc_out_format == YCBCR444) {
-               if (!hdmi_data->enc_color_depth)
-                       output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
-               else if (hdmi_data->enc_color_depth == 8) {
-                       color_depth = 4;
-                       output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
-               } else if (hdmi_data->enc_color_depth == 10)
-                       color_depth = 5;
-               else if (hdmi_data->enc_color_depth == 12)
-                       color_depth = 6;
-               else if (hdmi_data->enc_color_depth == 16)
-                       color_depth = 7;
-               else
-                       return;
-       } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) {
-               if (!hdmi_data->enc_color_depth ||
-                   hdmi_data->enc_color_depth == 8)
-                       remap_size = HDMI_VP_REMAP_YCC422_16bit;
-               else if (hdmi_data->enc_color_depth == 10)
-                       remap_size = HDMI_VP_REMAP_YCC422_20bit;
-               else if (hdmi_data->enc_color_depth == 12)
-                       remap_size = HDMI_VP_REMAP_YCC422_24bit;
-               else
-                       return;
-               output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
-       } else
-               return;
-
-       /* set the packetizer registers */
-       val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
-               HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
-               ((hdmi_data->pix_repet_factor <<
-               HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
-               HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
-       hdmi_writeb(hdmi, val, HDMI_VP_PR_CD);
-
-       hdmi_modb(hdmi, HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE,
-                 HDMI_VP_STUFF_PR_STUFFING_MASK, HDMI_VP_STUFF);
-
-       /* Data from pixel repeater block */
-       if (hdmi_data->pix_repet_factor > 1) {
-               vp_conf = HDMI_VP_CONF_PR_EN_ENABLE |
-                         HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER;
-       } else { /* data from packetizer block */
-               vp_conf = HDMI_VP_CONF_PR_EN_DISABLE |
-                         HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
-       }
-
-       hdmi_modb(hdmi, vp_conf,
-                 HDMI_VP_CONF_PR_EN_MASK |
-                 HDMI_VP_CONF_BYPASS_SELECT_MASK, HDMI_VP_CONF);
-
-       hdmi_modb(hdmi, 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET,
-                 HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, HDMI_VP_STUFF);
-
-       hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP);
-
-       if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) {
-               vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE |
-                         HDMI_VP_CONF_PP_EN_ENABLE |
-                         HDMI_VP_CONF_YCC422_EN_DISABLE;
-       } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) {
-               vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE |
-                         HDMI_VP_CONF_PP_EN_DISABLE |
-                         HDMI_VP_CONF_YCC422_EN_ENABLE;
-       } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) {
-               vp_conf = HDMI_VP_CONF_BYPASS_EN_ENABLE |
-                         HDMI_VP_CONF_PP_EN_DISABLE |
-                         HDMI_VP_CONF_YCC422_EN_DISABLE;
-       } else {
-               return;
-       }
-
-       hdmi_modb(hdmi, vp_conf,
-                 HDMI_VP_CONF_BYPASS_EN_MASK | HDMI_VP_CONF_PP_EN_ENMASK |
-                 HDMI_VP_CONF_YCC422_EN_MASK, HDMI_VP_CONF);
-
-       hdmi_modb(hdmi, HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
-                       HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE,
-                 HDMI_VP_STUFF_PP_STUFFING_MASK |
-                 HDMI_VP_STUFF_YCC422_STUFFING_MASK, HDMI_VP_STUFF);
-
-       hdmi_modb(hdmi, output_select, HDMI_VP_CONF_OUTPUT_SELECTOR_MASK,
-                 HDMI_VP_CONF);
-}
-
-static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi,
-                                               unsigned char bit)
-{
-       hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET,
-                 HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
-}
-
-static inline void hdmi_phy_test_enable(struct imx_hdmi *hdmi,
-                                               unsigned char bit)
-{
-       hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET,
-                 HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0);
-}
-
-static inline void hdmi_phy_test_clock(struct imx_hdmi *hdmi,
-                                               unsigned char bit)
-{
-       hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET,
-                 HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0);
-}
-
-static inline void hdmi_phy_test_din(struct imx_hdmi *hdmi,
-                                               unsigned char bit)
-{
-       hdmi_writeb(hdmi, bit, HDMI_PHY_TST1);
-}
-
-static inline void hdmi_phy_test_dout(struct imx_hdmi *hdmi,
-                                               unsigned char bit)
-{
-       hdmi_writeb(hdmi, bit, HDMI_PHY_TST2);
-}
-
-static bool hdmi_phy_wait_i2c_done(struct imx_hdmi *hdmi, int msec)
-{
-       while ((hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
-               if (msec-- == 0)
-                       return false;
-               udelay(1000);
-       }
-       return true;
-}
-
-static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
-                             unsigned char addr)
-{
-       hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0);
-       hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
-       hdmi_writeb(hdmi, (unsigned char)(data >> 8),
-               HDMI_PHY_I2CM_DATAO_1_ADDR);
-       hdmi_writeb(hdmi, (unsigned char)(data >> 0),
-               HDMI_PHY_I2CM_DATAO_0_ADDR);
-       hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
-               HDMI_PHY_I2CM_OPERATION_ADDR);
-       hdmi_phy_wait_i2c_done(hdmi, 1000);
-}
-
-static int hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
-                                    unsigned char addr)
-{
-       __hdmi_phy_i2c_write(hdmi, data, addr);
-       return 0;
-}
-
-static void imx_hdmi_phy_enable_power(struct imx_hdmi *hdmi, u8 enable)
-{
-       hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
-                        HDMI_PHY_CONF0_PDZ_OFFSET,
-                        HDMI_PHY_CONF0_PDZ_MASK);
-}
-
-static void imx_hdmi_phy_enable_tmds(struct imx_hdmi *hdmi, u8 enable)
-{
-       hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
-                        HDMI_PHY_CONF0_ENTMDS_OFFSET,
-                        HDMI_PHY_CONF0_ENTMDS_MASK);
-}
-
-static void imx_hdmi_phy_gen2_pddq(struct imx_hdmi *hdmi, u8 enable)
-{
-       hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
-                        HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
-                        HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
-}
-
-static void imx_hdmi_phy_gen2_txpwron(struct imx_hdmi *hdmi, u8 enable)
-{
-       hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
-                        HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
-                        HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
-}
-
-static void imx_hdmi_phy_sel_data_en_pol(struct imx_hdmi *hdmi, u8 enable)
-{
-       hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
-                        HDMI_PHY_CONF0_SELDATAENPOL_OFFSET,
-                        HDMI_PHY_CONF0_SELDATAENPOL_MASK);
-}
-
-static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable)
-{
-       hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
-                        HDMI_PHY_CONF0_SELDIPIF_OFFSET,
-                        HDMI_PHY_CONF0_SELDIPIF_MASK);
-}
-
-enum {
-       RES_8,
-       RES_10,
-       RES_12,
-       RES_MAX,
-};
-
-struct mpll_config {
-       unsigned long mpixelclock;
-       struct {
-               u16 cpce;
-               u16 gmp;
-       } res[RES_MAX];
-};
-
-static const struct mpll_config mpll_config[] = {
-       {
-               45250000, {
-                       { 0x01e0, 0x0000 },
-                       { 0x21e1, 0x0000 },
-                       { 0x41e2, 0x0000 }
-               },
-       }, {
-               92500000, {
-                       { 0x0140, 0x0005 },
-                       { 0x2141, 0x0005 },
-                       { 0x4142, 0x0005 },
-               },
-       }, {
-               148500000, {
-                       { 0x00a0, 0x000a },
-                       { 0x20a1, 0x000a },
-                       { 0x40a2, 0x000a },
-               },
-       }, {
-               ~0UL, {
-                       { 0x00a0, 0x000a },
-                       { 0x2001, 0x000f },
-                       { 0x4002, 0x000f },
-               },
-       }
-};
-
-struct curr_ctrl {
-       unsigned long mpixelclock;
-       u16 curr[RES_MAX];
-};
-
-static const struct curr_ctrl curr_ctrl[] = {
-       /*      pixelclk     bpp8    bpp10   bpp12 */
-       {
-                54000000, { 0x091c, 0x091c, 0x06dc },
-       }, {
-                58400000, { 0x091c, 0x06dc, 0x06dc },
-       }, {
-                72000000, { 0x06dc, 0x06dc, 0x091c },
-       }, {
-                74250000, { 0x06dc, 0x0b5c, 0x091c },
-       }, {
-               118800000, { 0x091c, 0x091c, 0x06dc },
-       }, {
-               216000000, { 0x06dc, 0x0b5c, 0x091c },
-       }
-};
-
-static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
-                             unsigned char res, int cscon)
-{
-       unsigned res_idx, i;
-       u8 val, msec;
-
-       if (prep)
-               return -EINVAL;
-
-       switch (res) {
-       case 0: /* color resolution 0 is 8 bit colour depth */
-       case 8:
-               res_idx = RES_8;
-               break;
-       case 10:
-               res_idx = RES_10;
-               break;
-       case 12:
-               res_idx = RES_12;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* Enable csc path */
-       if (cscon)
-               val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
-       else
-               val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;
-
-       hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL);
-
-       /* gen2 tx power off */
-       imx_hdmi_phy_gen2_txpwron(hdmi, 0);
-
-       /* gen2 pddq */
-       imx_hdmi_phy_gen2_pddq(hdmi, 1);
-
-       /* PHY reset */
-       hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
-       hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
-
-       hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
-
-       hdmi_phy_test_clear(hdmi, 1);
-       hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
-                       HDMI_PHY_I2CM_SLAVE_ADDR);
-       hdmi_phy_test_clear(hdmi, 0);
-
-       /* PLL/MPLL Cfg - always match on final entry */
-       for (i = 0; i < ARRAY_SIZE(mpll_config) - 1; i++)
-               if (hdmi->hdmi_data.video_mode.mpixelclock <=
-                   mpll_config[i].mpixelclock)
-                       break;
-
-       hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].cpce, 0x06);
-       hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].gmp, 0x15);
-
-       for (i = 0; i < ARRAY_SIZE(curr_ctrl); i++)
-               if (hdmi->hdmi_data.video_mode.mpixelclock <=
-                   curr_ctrl[i].mpixelclock)
-                       break;
-
-       if (i >= ARRAY_SIZE(curr_ctrl)) {
-               dev_err(hdmi->dev,
-                               "Pixel clock %d - unsupported by HDMI\n",
-                               hdmi->hdmi_data.video_mode.mpixelclock);
-               return -EINVAL;
-       }
-
-       /* CURRCTRL */
-       hdmi_phy_i2c_write(hdmi, curr_ctrl[i].curr[res_idx], 0x10);
-
-       hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);  /* PLLPHBYCTRL */
-       hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
-       /* RESISTANCE TERM 133Ohm Cfg */
-       hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);  /* TXTERM */
-       /* PREEMP Cgf 0.00 */
-       hdmi_phy_i2c_write(hdmi, 0x800d, 0x09);  /* CKSYMTXCTRL */
-       /* TX/CK LVL 10 */
-       hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E);  /* VLEVCTRL */
-       /* REMOVE CLK TERM */
-       hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);  /* CKCALCTRL */
-
-       imx_hdmi_phy_enable_power(hdmi, 1);
-
-       /* toggle TMDS enable */
-       imx_hdmi_phy_enable_tmds(hdmi, 0);
-       imx_hdmi_phy_enable_tmds(hdmi, 1);
-
-       /* gen2 tx power on */
-       imx_hdmi_phy_gen2_txpwron(hdmi, 1);
-       imx_hdmi_phy_gen2_pddq(hdmi, 0);
-
-       /*Wait for PHY PLL lock */
-       msec = 5;
-       do {
-               val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
-               if (!val)
-                       break;
-
-               if (msec == 0) {
-                       dev_err(hdmi->dev, "PHY PLL not locked\n");
-                       return -ETIMEDOUT;
-               }
-
-               udelay(1000);
-               msec--;
-       } while (1);
-
-       return 0;
-}
-
-static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
-{
-       int i, ret;
-       bool cscon = false;
-
-       /*check csc whether needed activated in HDMI mode */
-       cscon = (is_color_space_conversion(hdmi) &&
-                       !hdmi->hdmi_data.video_mode.mdvi);
-
-       /* HDMI Phy spec says to do the phy initialization sequence twice */
-       for (i = 0; i < 2; i++) {
-               imx_hdmi_phy_sel_data_en_pol(hdmi, 1);
-               imx_hdmi_phy_sel_interface_control(hdmi, 0);
-               imx_hdmi_phy_enable_tmds(hdmi, 0);
-               imx_hdmi_phy_enable_power(hdmi, 0);
-
-               /* Enable CSC */
-               ret = hdmi_phy_configure(hdmi, 0, 8, cscon);
-               if (ret)
-                       return ret;
-       }
-
-       hdmi->phy_enabled = true;
-       return 0;
-}
-
-static void hdmi_tx_hdcp_config(struct imx_hdmi *hdmi)
-{
-       u8 de;
-
-       if (hdmi->hdmi_data.video_mode.mdataenablepolarity)
-               de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH;
-       else
-               de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW;
-
-       /* disable rx detect */
-       hdmi_modb(hdmi, HDMI_A_HDCPCFG0_RXDETECT_DISABLE,
-                 HDMI_A_HDCPCFG0_RXDETECT_MASK, HDMI_A_HDCPCFG0);
-
-       hdmi_modb(hdmi, de, HDMI_A_VIDPOLCFG_DATAENPOL_MASK, HDMI_A_VIDPOLCFG);
-
-       hdmi_modb(hdmi, HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE,
-                 HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1);
-}
-
-static void hdmi_config_AVI(struct imx_hdmi *hdmi)
-{
-       u8 val, pix_fmt, under_scan;
-       u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry;
-       bool aspect_16_9;
-
-       aspect_16_9 = false; /* FIXME */
-
-       /* AVI Data Byte 1 */
-       if (hdmi->hdmi_data.enc_out_format == YCBCR444)
-               pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR444;
-       else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS)
-               pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR422;
-       else
-               pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB;
-
-               under_scan =  HDMI_FC_AVICONF0_SCAN_INFO_NODATA;
-
-       /*
-        * Active format identification data is present in the AVI InfoFrame.
-        * Under scan info, no bar data
-        */
-       val = pix_fmt | under_scan |
-               HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT |
-               HDMI_FC_AVICONF0_BAR_DATA_NO_DATA;
-
-       hdmi_writeb(hdmi, val, HDMI_FC_AVICONF0);
-
-       /* AVI Data Byte 2 -Set the Aspect Ratio */
-       if (aspect_16_9) {
-               act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9;
-               coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9;
-       } else {
-               act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3;
-               coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3;
-       }
-
-       /* Set up colorimetry */
-       if (hdmi->hdmi_data.enc_out_format == XVYCC444) {
-               colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO;
-               if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
-                       ext_colorimetry =
-                               HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
-               else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/
-                       ext_colorimetry =
-                               HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709;
-       } else if (hdmi->hdmi_data.enc_out_format != RGB) {
-               if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
-                       colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE;
-               else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/
-                       colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR;
-               ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
-       } else { /* Carries no data */
-               colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA;
-               ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
-       }
-
-       val = colorimetry | coded_ratio | act_ratio;
-       hdmi_writeb(hdmi, val, HDMI_FC_AVICONF1);
-
-       /* AVI Data Byte 3 */
-       val = HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA | ext_colorimetry |
-               HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT |
-               HDMI_FC_AVICONF2_SCALING_NONE;
-       hdmi_writeb(hdmi, val, HDMI_FC_AVICONF2);
-
-       /* AVI Data Byte 4 */
-       hdmi_writeb(hdmi, hdmi->vic, HDMI_FC_AVIVID);
-
-       /* AVI Data Byte 5- set up input and output pixel repetition */
-       val = (((hdmi->hdmi_data.video_mode.mpixelrepetitioninput + 1) <<
-               HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) &
-               HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) |
-               ((hdmi->hdmi_data.video_mode.mpixelrepetitionoutput <<
-               HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) &
-               HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK);
-       hdmi_writeb(hdmi, val, HDMI_FC_PRCONF);
-
-       /* IT Content and quantization range = don't care */
-       val = HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS |
-               HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED;
-       hdmi_writeb(hdmi, val, HDMI_FC_AVICONF3);
-
-       /* AVI Data Bytes 6-13 */
-       hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB0);
-       hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB1);
-       hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB0);
-       hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB1);
-       hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB0);
-       hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB1);
-       hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB0);
-       hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB1);
-}
-
-static void hdmi_av_composer(struct imx_hdmi *hdmi,
-                            const struct drm_display_mode *mode)
-{
-       u8 inv_val;
-       struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
-       int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
-
-       vmode->mhsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PHSYNC);
-       vmode->mvsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PVSYNC);
-       vmode->minterlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
-       vmode->mpixelclock = mode->clock * 1000;
-
-       dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
-
-       /* Set up HDMI_FC_INVIDCONF */
-       inv_val = (hdmi->hdmi_data.hdcp_enable ?
-               HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
-               HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE);
-
-       inv_val |= (vmode->mvsyncpolarity ?
-               HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
-               HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW);
-
-       inv_val |= (vmode->mhsyncpolarity ?
-               HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
-               HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW);
-
-       inv_val |= (vmode->mdataenablepolarity ?
-               HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
-               HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
-
-       if (hdmi->vic == 39)
-               inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH;
-       else
-               inv_val |= (vmode->minterlaced ?
-                       HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH :
-                       HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW);
-
-       inv_val |= (vmode->minterlaced ?
-               HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
-               HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE);
-
-       inv_val |= (vmode->mdvi ?
-               HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE :
-               HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE);
-
-       hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF);
-
-       /* Set up horizontal active pixel width */
-       hdmi_writeb(hdmi, mode->hdisplay >> 8, HDMI_FC_INHACTV1);
-       hdmi_writeb(hdmi, mode->hdisplay, HDMI_FC_INHACTV0);
-
-       /* Set up vertical active lines */
-       hdmi_writeb(hdmi, mode->vdisplay >> 8, HDMI_FC_INVACTV1);
-       hdmi_writeb(hdmi, mode->vdisplay, HDMI_FC_INVACTV0);
-
-       /* Set up horizontal blanking pixel region width */
-       hblank = mode->htotal - mode->hdisplay;
-       hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1);
-       hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0);
-
-       /* Set up vertical blanking pixel region width */
-       vblank = mode->vtotal - mode->vdisplay;
-       hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK);
-
-       /* Set up HSYNC active edge delay width (in pixel clks) */
-       h_de_hs = mode->hsync_start - mode->hdisplay;
-       hdmi_writeb(hdmi, h_de_hs >> 8, HDMI_FC_HSYNCINDELAY1);
-       hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0);
-
-       /* Set up VSYNC active edge delay (in lines) */
-       v_de_vs = mode->vsync_start - mode->vdisplay;
-       hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY);
-
-       /* Set up HSYNC active pulse width (in pixel clks) */
-       hsync_len = mode->hsync_end - mode->hsync_start;
-       hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1);
-       hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0);
-
-       /* Set up VSYNC active edge delay (in lines) */
-       vsync_len = mode->vsync_end - mode->vsync_start;
-       hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
-}
-
-static void imx_hdmi_phy_disable(struct imx_hdmi *hdmi)
-{
-       if (!hdmi->phy_enabled)
-               return;
-
-       imx_hdmi_phy_enable_tmds(hdmi, 0);
-       imx_hdmi_phy_enable_power(hdmi, 0);
-
-       hdmi->phy_enabled = false;
-}
-
-/* HDMI Initialization Step B.4 */
-static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi)
-{
-       u8 clkdis;
-
-       /* control period minimum duration */
-       hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
-       hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
-       hdmi_writeb(hdmi, 1, HDMI_FC_EXCTRLSPAC);
-
-       /* Set to fill TMDS data channels */
-       hdmi_writeb(hdmi, 0x0B, HDMI_FC_CH0PREAM);
-       hdmi_writeb(hdmi, 0x16, HDMI_FC_CH1PREAM);
-       hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
-
-       /* Enable pixel clock and tmds data path */
-       clkdis = 0x7F;
-       clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
-       hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
-
-       clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
-       hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
-
-       /* Enable csc path */
-       if (is_color_space_conversion(hdmi)) {
-               clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
-               hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
-       }
-}
-
-static void hdmi_enable_audio_clk(struct imx_hdmi *hdmi)
-{
-       hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS);
-}
-
-/* Workaround to clear the overflow condition */
-static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi)
-{
-       int count;
-       u8 val;
-
-       /* TMDS software reset */
-       hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
-
-       val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF);
-       if (hdmi->dev_type == IMX6DL_HDMI) {
-               hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
-               return;
-       }
-
-       for (count = 0; count < 4; count++)
-               hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
-}
-
-static void hdmi_enable_overflow_interrupts(struct imx_hdmi *hdmi)
-{
-       hdmi_writeb(hdmi, 0, HDMI_FC_MASK2);
-       hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2);
-}
-
-static void hdmi_disable_overflow_interrupts(struct imx_hdmi *hdmi)
-{
-       hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
-                   HDMI_IH_MUTE_FC_STAT2);
-}
-
-static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
-{
-       int ret;
-
-       hdmi_disable_overflow_interrupts(hdmi);
-
-       hdmi->vic = drm_match_cea_mode(mode);
-
-       if (!hdmi->vic) {
-               dev_dbg(hdmi->dev, "Non-CEA mode used in HDMI\n");
-               hdmi->hdmi_data.video_mode.mdvi = true;
-       } else {
-               dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic);
-               hdmi->hdmi_data.video_mode.mdvi = false;
-       }
-
-       if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
-               (hdmi->vic == 21) || (hdmi->vic == 22) ||
-               (hdmi->vic == 2) || (hdmi->vic == 3) ||
-               (hdmi->vic == 17) || (hdmi->vic == 18))
-               hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
-       else
-               hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
-
-       if ((hdmi->vic == 10) || (hdmi->vic == 11) ||
-               (hdmi->vic == 12) || (hdmi->vic == 13) ||
-               (hdmi->vic == 14) || (hdmi->vic == 15) ||
-               (hdmi->vic == 25) || (hdmi->vic == 26) ||
-               (hdmi->vic == 27) || (hdmi->vic == 28) ||
-               (hdmi->vic == 29) || (hdmi->vic == 30) ||
-               (hdmi->vic == 35) || (hdmi->vic == 36) ||
-               (hdmi->vic == 37) || (hdmi->vic == 38))
-               hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1;
-       else
-               hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
-
-       hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
-
-       /* TODO: Get input format from IPU (via FB driver interface) */
-       hdmi->hdmi_data.enc_in_format = RGB;
-
-       hdmi->hdmi_data.enc_out_format = RGB;
-
-       hdmi->hdmi_data.enc_color_depth = 8;
-       hdmi->hdmi_data.pix_repet_factor = 0;
-       hdmi->hdmi_data.hdcp_enable = 0;
-       hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
-
-       /* HDMI Initialization Step B.1 */
-       hdmi_av_composer(hdmi, mode);
-
-       /* HDMI Initializateion Step B.2 */
-       ret = imx_hdmi_phy_init(hdmi);
-       if (ret)
-               return ret;
-
-       /* HDMI Initialization Step B.3 */
-       imx_hdmi_enable_video_path(hdmi);
-
-       /* not for DVI mode */
-       if (hdmi->hdmi_data.video_mode.mdvi)
-               dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
-       else {
-               dev_dbg(hdmi->dev, "%s CEA mode\n", __func__);
-
-               /* HDMI Initialization Step E - Configure audio */
-               hdmi_clk_regenerator_update_pixel_clock(hdmi);
-               hdmi_enable_audio_clk(hdmi);
-
-               /* HDMI Initialization Step F - Configure AVI InfoFrame */
-               hdmi_config_AVI(hdmi);
-       }
-
-       hdmi_video_packetize(hdmi);
-       hdmi_video_csc(hdmi);
-       hdmi_video_sample(hdmi);
-       hdmi_tx_hdcp_config(hdmi);
-
-       imx_hdmi_clear_overflow(hdmi);
-       if (hdmi->cable_plugin && !hdmi->hdmi_data.video_mode.mdvi)
-               hdmi_enable_overflow_interrupts(hdmi);
-
-       return 0;
-}
-
-/* Wait until we are registered to enable interrupts */
-static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi)
-{
-       hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
-                   HDMI_PHY_I2CM_INT_ADDR);
-
-       hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
-                   HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
-                   HDMI_PHY_I2CM_CTLINT_ADDR);
-
-       /* enable cable hot plug irq */
-       hdmi_writeb(hdmi, (u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0);
-
-       /* Clear Hotplug interrupts */
-       hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
-
-       return 0;
-}
-
-static void initialize_hdmi_ih_mutes(struct imx_hdmi *hdmi)
-{
-       u8 ih_mute;
-
-       /*
-        * Boot up defaults are:
-        * HDMI_IH_MUTE   = 0x03 (disabled)
-        * HDMI_IH_MUTE_* = 0x00 (enabled)
-        *
-        * Disable top level interrupt bits in HDMI block
-        */
-       ih_mute = hdmi_readb(hdmi, HDMI_IH_MUTE) |
-                 HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
-                 HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;
-
-       hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
-
-       /* by default mask all interrupts */
-       hdmi_writeb(hdmi, 0xff, HDMI_VP_MASK);
-       hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK0);
-       hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK1);
-       hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK2);
-       hdmi_writeb(hdmi, 0xff, HDMI_PHY_MASK0);
-       hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_INT_ADDR);
-       hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_CTLINT_ADDR);
-       hdmi_writeb(hdmi, 0xff, HDMI_AUD_INT);
-       hdmi_writeb(hdmi, 0xff, HDMI_AUD_SPDIFINT);
-       hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
-       hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
-       hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
-       hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
-       hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
-       hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
-
-       /* Disable interrupts in the IH_MUTE_* registers */
-       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT0);
-       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT1);
-       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT2);
-       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AS_STAT0);
-       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_PHY_STAT0);
-       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CM_STAT0);
-       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_CEC_STAT0);
-       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_VP_STAT0);
-       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CMPHY_STAT0);
-       hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
-
-       /* Enable top level interrupt bits in HDMI block */
-       ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
-                   HDMI_IH_MUTE_MUTE_ALL_INTERRUPT);
-       hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
-}
-
-static void imx_hdmi_poweron(struct imx_hdmi *hdmi)
-{
-       imx_hdmi_setup(hdmi, &hdmi->previous_mode);
-}
-
-static void imx_hdmi_poweroff(struct imx_hdmi *hdmi)
-{
-       imx_hdmi_phy_disable(hdmi);
-}
-
-static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector
-                                                       *connector, bool force)
-{
-       struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
-                                            connector);
-
-       return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
-               connector_status_connected : connector_status_disconnected;
-}
-
-static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
-{
-       struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
-                                            connector);
-       struct edid *edid;
-       int ret;
-
-       if (!hdmi->ddc)
-               return 0;
-
-       edid = drm_get_edid(connector, hdmi->ddc);
-       if (edid) {
-               dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
-                       edid->width_cm, edid->height_cm);
-
-               drm_mode_connector_update_edid_property(connector, edid);
-               ret = drm_add_edid_modes(connector, edid);
-               kfree(edid);
-       } else {
-               dev_dbg(hdmi->dev, "failed to get edid\n");
-       }
-
-       return 0;
-}
-
-static struct drm_encoder *imx_hdmi_connector_best_encoder(struct drm_connector
-                                                          *connector)
-{
-       struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
-                                            connector);
-
-       return &hdmi->encoder;
-}
-
-static void imx_hdmi_encoder_mode_set(struct drm_encoder *encoder,
-                       struct drm_display_mode *mode,
-                       struct drm_display_mode *adjusted_mode)
-{
-       struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
-
-       imx_hdmi_setup(hdmi, mode);
-
-       /* Store the display mode for plugin/DKMS poweron events */
-       memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
-}
-
-static bool imx_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
-                       const struct drm_display_mode *mode,
-                       struct drm_display_mode *adjusted_mode)
-{
-       return true;
-}
-
-static void imx_hdmi_encoder_disable(struct drm_encoder *encoder)
-{
-}
-
-static void imx_hdmi_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-       struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
-
-       if (mode)
-               imx_hdmi_poweroff(hdmi);
-       else
-               imx_hdmi_poweron(hdmi);
-}
-
-static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder)
-{
-       struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
-
-       imx_hdmi_poweroff(hdmi);
-       imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24);
-}
-
-static void imx_hdmi_encoder_commit(struct drm_encoder *encoder)
-{
-       struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
-       int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder);
-
-       imx_hdmi_set_ipu_di_mux(hdmi, mux);
-
-       imx_hdmi_poweron(hdmi);
-}
-
-static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
-       .destroy = imx_drm_encoder_destroy,
-};
-
-static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = {
-       .dpms = imx_hdmi_encoder_dpms,
-       .prepare = imx_hdmi_encoder_prepare,
-       .commit = imx_hdmi_encoder_commit,
-       .mode_set = imx_hdmi_encoder_mode_set,
-       .mode_fixup = imx_hdmi_encoder_mode_fixup,
-       .disable = imx_hdmi_encoder_disable,
-};
-
-static struct drm_connector_funcs imx_hdmi_connector_funcs = {
-       .dpms = drm_helper_connector_dpms,
-       .fill_modes = drm_helper_probe_single_connector_modes,
-       .detect = imx_hdmi_connector_detect,
-       .destroy = imx_drm_connector_destroy,
-};
-
-static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = {
-       .get_modes = imx_hdmi_connector_get_modes,
-       .best_encoder = imx_hdmi_connector_best_encoder,
-};
-
-static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id)
-{
-       struct imx_hdmi *hdmi = dev_id;
-       u8 intr_stat;
-
-       intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
-       if (intr_stat)
-               hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
-
-       return intr_stat ? IRQ_WAKE_THREAD : IRQ_NONE;
-}
-
-static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
-{
-       struct imx_hdmi *hdmi = dev_id;
-       u8 intr_stat;
-       u8 phy_int_pol;
-
-       intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
-
-       phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0);
-
-       if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
-               if (phy_int_pol & HDMI_PHY_HPD) {
-                       dev_dbg(hdmi->dev, "EVENT=plugin\n");
-
-                       hdmi_modb(hdmi, 0, HDMI_PHY_HPD, HDMI_PHY_POL0);
-
-                       imx_hdmi_poweron(hdmi);
-               } else {
-                       dev_dbg(hdmi->dev, "EVENT=plugout\n");
-
-                       hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD,
-                               HDMI_PHY_POL0);
-
-                       imx_hdmi_poweroff(hdmi);
-               }
-               drm_helper_hpd_irq_event(hdmi->connector.dev);
-       }
-
-       hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
-       hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
-
-       return IRQ_HANDLED;
-}
-
-static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi)
-{
-       int ret;
-
-       ret = imx_drm_encoder_parse_of(drm, &hdmi->encoder,
-                                      hdmi->dev->of_node);
-       if (ret)
-               return ret;
-
-       hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD;
-
-       drm_encoder_helper_add(&hdmi->encoder, &imx_hdmi_encoder_helper_funcs);
-       drm_encoder_init(drm, &hdmi->encoder, &imx_hdmi_encoder_funcs,
-                        DRM_MODE_ENCODER_TMDS);
-
-       drm_connector_helper_add(&hdmi->connector,
-                       &imx_hdmi_connector_helper_funcs);
-       drm_connector_init(drm, &hdmi->connector, &imx_hdmi_connector_funcs,
-                          DRM_MODE_CONNECTOR_HDMIA);
-
-       hdmi->connector.encoder = &hdmi->encoder;
-
-       drm_mode_connector_attach_encoder(&hdmi->connector, &hdmi->encoder);
-
-       return 0;
-}
-
-static struct platform_device_id imx_hdmi_devtype[] = {
-       {
-               .name = "imx6q-hdmi",
-               .driver_data = IMX6Q_HDMI,
-       }, {
-               .name = "imx6dl-hdmi",
-               .driver_data = IMX6DL_HDMI,
-       }, { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype);
-
-static const struct of_device_id imx_hdmi_dt_ids[] = {
-{ .compatible = "fsl,imx6q-hdmi", .data = &imx_hdmi_devtype[IMX6Q_HDMI], },
-{ .compatible = "fsl,imx6dl-hdmi", .data = &imx_hdmi_devtype[IMX6DL_HDMI], },
-{ /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
-
-static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       const struct of_device_id *of_id =
-                               of_match_device(imx_hdmi_dt_ids, dev);
-       struct drm_device *drm = data;
-       struct device_node *np = dev->of_node;
-       struct device_node *ddc_node;
-       struct imx_hdmi *hdmi;
-       struct resource *iores;
-       int ret, irq;
-
-       hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
-       if (!hdmi)
-               return -ENOMEM;
-
-       hdmi->dev = dev;
-       hdmi->sample_rate = 48000;
-       hdmi->ratio = 100;
-
-       if (of_id) {
-               const struct platform_device_id *device_id = of_id->data;
-
-               hdmi->dev_type = device_id->driver_data;
-       }
-
-       ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
-       if (ddc_node) {
-               hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
-               if (!hdmi->ddc)
-                       dev_dbg(hdmi->dev, "failed to read ddc node\n");
-
-               of_node_put(ddc_node);
-       } else {
-               dev_dbg(hdmi->dev, "no ddc property found\n");
-       }
-
-       irq = platform_get_irq(pdev, 0);
-       if (irq < 0)
-               return irq;
-
-       ret = devm_request_threaded_irq(dev, irq, imx_hdmi_hardirq,
-                                       imx_hdmi_irq, IRQF_SHARED,
-                                       dev_name(dev), hdmi);
-       if (ret)
-               return ret;
-
-       iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       hdmi->regs = devm_ioremap_resource(dev, iores);
-       if (IS_ERR(hdmi->regs))
-               return PTR_ERR(hdmi->regs);
-
-       hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
-       if (IS_ERR(hdmi->regmap))
-               return PTR_ERR(hdmi->regmap);
-
-       hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
-       if (IS_ERR(hdmi->isfr_clk)) {
-               ret = PTR_ERR(hdmi->isfr_clk);
-               dev_err(hdmi->dev,
-                       "Unable to get HDMI isfr clk: %d\n", ret);
-               return ret;
-       }
-
-       ret = clk_prepare_enable(hdmi->isfr_clk);
-       if (ret) {
-               dev_err(hdmi->dev,
-                       "Cannot enable HDMI isfr clock: %d\n", ret);
-               return ret;
-       }
-
-       hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb");
-       if (IS_ERR(hdmi->iahb_clk)) {
-               ret = PTR_ERR(hdmi->iahb_clk);
-               dev_err(hdmi->dev,
-                       "Unable to get HDMI iahb clk: %d\n", ret);
-               goto err_isfr;
-       }
-
-       ret = clk_prepare_enable(hdmi->iahb_clk);
-       if (ret) {
-               dev_err(hdmi->dev,
-                       "Cannot enable HDMI iahb clock: %d\n", ret);
-               goto err_isfr;
-       }
-
-       /* Product and revision IDs */
-       dev_info(dev,
-               "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
-               hdmi_readb(hdmi, HDMI_DESIGN_ID),
-               hdmi_readb(hdmi, HDMI_REVISION_ID),
-               hdmi_readb(hdmi, HDMI_PRODUCT_ID0),
-               hdmi_readb(hdmi, HDMI_PRODUCT_ID1));
-
-       initialize_hdmi_ih_mutes(hdmi);
-
-       /*
-        * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
-        * N and cts values before enabling phy
-        */
-       hdmi_init_clk_regenerator(hdmi);
-
-       /*
-        * Configure registers related to HDMI interrupt
-        * generation before registering IRQ.
-        */
-       hdmi_writeb(hdmi, HDMI_PHY_HPD, HDMI_PHY_POL0);
-
-       /* Clear Hotplug interrupts */
-       hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
-
-       ret = imx_hdmi_fb_registered(hdmi);
-       if (ret)
-               goto err_iahb;
-
-       ret = imx_hdmi_register(drm, hdmi);
-       if (ret)
-               goto err_iahb;
-
-       /* Unmute interrupts */
-       hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
-
-       dev_set_drvdata(dev, hdmi);
-
-       return 0;
-
-err_iahb:
-       clk_disable_unprepare(hdmi->iahb_clk);
-err_isfr:
-       clk_disable_unprepare(hdmi->isfr_clk);
-
-       return ret;
-}
-
-static void imx_hdmi_unbind(struct device *dev, struct device *master,
-       void *data)
-{
-       struct imx_hdmi *hdmi = dev_get_drvdata(dev);
-
-       /* Disable all interrupts */
-       hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
-
-       hdmi->connector.funcs->destroy(&hdmi->connector);
-       hdmi->encoder.funcs->destroy(&hdmi->encoder);
-
-       clk_disable_unprepare(hdmi->iahb_clk);
-       clk_disable_unprepare(hdmi->isfr_clk);
-       i2c_put_adapter(hdmi->ddc);
-}
-
-static const struct component_ops hdmi_ops = {
-       .bind   = imx_hdmi_bind,
-       .unbind = imx_hdmi_unbind,
-};
-
-static int imx_hdmi_platform_probe(struct platform_device *pdev)
-{
-       return component_add(&pdev->dev, &hdmi_ops);
-}
-
-static int imx_hdmi_platform_remove(struct platform_device *pdev)
-{
-       component_del(&pdev->dev, &hdmi_ops);
-       return 0;
-}
-
-static struct platform_driver imx_hdmi_driver = {
-       .probe  = imx_hdmi_platform_probe,
-       .remove = imx_hdmi_platform_remove,
-       .driver = {
-               .name = "imx-hdmi",
-               .owner = THIS_MODULE,
-               .of_match_table = imx_hdmi_dt_ids,
-       },
-};
-
-module_platform_driver(imx_hdmi_driver);
-
-MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
-MODULE_DESCRIPTION("i.MX6 HDMI transmitter driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-hdmi");
diff --git a/drivers/staging/imx-drm/imx-hdmi.h b/drivers/staging/imx-drm/imx-hdmi.h
deleted file mode 100644 (file)
index 39b6776..0000000
+++ /dev/null
@@ -1,1032 +0,0 @@
-/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __IMX_HDMI_H__
-#define __IMX_HDMI_H__
-
-/* Identification Registers */
-#define HDMI_DESIGN_ID                          0x0000
-#define HDMI_REVISION_ID                        0x0001
-#define HDMI_PRODUCT_ID0                        0x0002
-#define HDMI_PRODUCT_ID1                        0x0003
-#define HDMI_CONFIG0_ID                         0x0004
-#define HDMI_CONFIG1_ID                         0x0005
-#define HDMI_CONFIG2_ID                         0x0006
-#define HDMI_CONFIG3_ID                         0x0007
-
-/* Interrupt Registers */
-#define HDMI_IH_FC_STAT0                        0x0100
-#define HDMI_IH_FC_STAT1                        0x0101
-#define HDMI_IH_FC_STAT2                        0x0102
-#define HDMI_IH_AS_STAT0                        0x0103
-#define HDMI_IH_PHY_STAT0                       0x0104
-#define HDMI_IH_I2CM_STAT0                      0x0105
-#define HDMI_IH_CEC_STAT0                       0x0106
-#define HDMI_IH_VP_STAT0                        0x0107
-#define HDMI_IH_I2CMPHY_STAT0                   0x0108
-#define HDMI_IH_AHBDMAAUD_STAT0                 0x0109
-
-#define HDMI_IH_MUTE_FC_STAT0                   0x0180
-#define HDMI_IH_MUTE_FC_STAT1                   0x0181
-#define HDMI_IH_MUTE_FC_STAT2                   0x0182
-#define HDMI_IH_MUTE_AS_STAT0                   0x0183
-#define HDMI_IH_MUTE_PHY_STAT0                  0x0184
-#define HDMI_IH_MUTE_I2CM_STAT0                 0x0185
-#define HDMI_IH_MUTE_CEC_STAT0                  0x0186
-#define HDMI_IH_MUTE_VP_STAT0                   0x0187
-#define HDMI_IH_MUTE_I2CMPHY_STAT0              0x0188
-#define HDMI_IH_MUTE_AHBDMAAUD_STAT0            0x0189
-#define HDMI_IH_MUTE                            0x01FF
-
-/* Video Sample Registers */
-#define HDMI_TX_INVID0                          0x0200
-#define HDMI_TX_INSTUFFING                      0x0201
-#define HDMI_TX_GYDATA0                         0x0202
-#define HDMI_TX_GYDATA1                         0x0203
-#define HDMI_TX_RCRDATA0                        0x0204
-#define HDMI_TX_RCRDATA1                        0x0205
-#define HDMI_TX_BCBDATA0                        0x0206
-#define HDMI_TX_BCBDATA1                        0x0207
-
-/* Video Packetizer Registers */
-#define HDMI_VP_STATUS                          0x0800
-#define HDMI_VP_PR_CD                           0x0801
-#define HDMI_VP_STUFF                           0x0802
-#define HDMI_VP_REMAP                           0x0803
-#define HDMI_VP_CONF                            0x0804
-#define HDMI_VP_STAT                            0x0805
-#define HDMI_VP_INT                             0x0806
-#define HDMI_VP_MASK                            0x0807
-#define HDMI_VP_POL                             0x0808
-
-/* Frame Composer Registers */
-#define HDMI_FC_INVIDCONF                       0x1000
-#define HDMI_FC_INHACTV0                        0x1001
-#define HDMI_FC_INHACTV1                        0x1002
-#define HDMI_FC_INHBLANK0                       0x1003
-#define HDMI_FC_INHBLANK1                       0x1004
-#define HDMI_FC_INVACTV0                        0x1005
-#define HDMI_FC_INVACTV1                        0x1006
-#define HDMI_FC_INVBLANK                        0x1007
-#define HDMI_FC_HSYNCINDELAY0                   0x1008
-#define HDMI_FC_HSYNCINDELAY1                   0x1009
-#define HDMI_FC_HSYNCINWIDTH0                   0x100A
-#define HDMI_FC_HSYNCINWIDTH1                   0x100B
-#define HDMI_FC_VSYNCINDELAY                    0x100C
-#define HDMI_FC_VSYNCINWIDTH                    0x100D
-#define HDMI_FC_INFREQ0                         0x100E
-#define HDMI_FC_INFREQ1                         0x100F
-#define HDMI_FC_INFREQ2                         0x1010
-#define HDMI_FC_CTRLDUR                         0x1011
-#define HDMI_FC_EXCTRLDUR                       0x1012
-#define HDMI_FC_EXCTRLSPAC                      0x1013
-#define HDMI_FC_CH0PREAM                        0x1014
-#define HDMI_FC_CH1PREAM                        0x1015
-#define HDMI_FC_CH2PREAM                        0x1016
-#define HDMI_FC_AVICONF3                        0x1017
-#define HDMI_FC_GCP                             0x1018
-#define HDMI_FC_AVICONF0                        0x1019
-#define HDMI_FC_AVICONF1                        0x101A
-#define HDMI_FC_AVICONF2                        0x101B
-#define HDMI_FC_AVIVID                          0x101C
-#define HDMI_FC_AVIETB0                         0x101D
-#define HDMI_FC_AVIETB1                         0x101E
-#define HDMI_FC_AVISBB0                         0x101F
-#define HDMI_FC_AVISBB1                         0x1020
-#define HDMI_FC_AVIELB0                         0x1021
-#define HDMI_FC_AVIELB1                         0x1022
-#define HDMI_FC_AVISRB0                         0x1023
-#define HDMI_FC_AVISRB1                         0x1024
-#define HDMI_FC_AUDICONF0                       0x1025
-#define HDMI_FC_AUDICONF1                       0x1026
-#define HDMI_FC_AUDICONF2                       0x1027
-#define HDMI_FC_AUDICONF3                       0x1028
-#define HDMI_FC_VSDIEEEID0                      0x1029
-#define HDMI_FC_VSDSIZE                         0x102A
-#define HDMI_FC_VSDIEEEID1                      0x1030
-#define HDMI_FC_VSDIEEEID2                      0x1031
-#define HDMI_FC_VSDPAYLOAD0                     0x1032
-#define HDMI_FC_VSDPAYLOAD1                     0x1033
-#define HDMI_FC_VSDPAYLOAD2                     0x1034
-#define HDMI_FC_VSDPAYLOAD3                     0x1035
-#define HDMI_FC_VSDPAYLOAD4                     0x1036
-#define HDMI_FC_VSDPAYLOAD5                     0x1037
-#define HDMI_FC_VSDPAYLOAD6                     0x1038
-#define HDMI_FC_VSDPAYLOAD7                     0x1039
-#define HDMI_FC_VSDPAYLOAD8                     0x103A
-#define HDMI_FC_VSDPAYLOAD9                     0x103B
-#define HDMI_FC_VSDPAYLOAD10                    0x103C
-#define HDMI_FC_VSDPAYLOAD11                    0x103D
-#define HDMI_FC_VSDPAYLOAD12                    0x103E
-#define HDMI_FC_VSDPAYLOAD13                    0x103F
-#define HDMI_FC_VSDPAYLOAD14                    0x1040
-#define HDMI_FC_VSDPAYLOAD15                    0x1041
-#define HDMI_FC_VSDPAYLOAD16                    0x1042
-#define HDMI_FC_VSDPAYLOAD17                    0x1043
-#define HDMI_FC_VSDPAYLOAD18                    0x1044
-#define HDMI_FC_VSDPAYLOAD19                    0x1045
-#define HDMI_FC_VSDPAYLOAD20                    0x1046
-#define HDMI_FC_VSDPAYLOAD21                    0x1047
-#define HDMI_FC_VSDPAYLOAD22                    0x1048
-#define HDMI_FC_VSDPAYLOAD23                    0x1049
-#define HDMI_FC_SPDVENDORNAME0                  0x104A
-#define HDMI_FC_SPDVENDORNAME1                  0x104B
-#define HDMI_FC_SPDVENDORNAME2                  0x104C
-#define HDMI_FC_SPDVENDORNAME3                  0x104D
-#define HDMI_FC_SPDVENDORNAME4                  0x104E
-#define HDMI_FC_SPDVENDORNAME5                  0x104F
-#define HDMI_FC_SPDVENDORNAME6                  0x1050
-#define HDMI_FC_SPDVENDORNAME7                  0x1051
-#define HDMI_FC_SDPPRODUCTNAME0                 0x1052
-#define HDMI_FC_SDPPRODUCTNAME1                 0x1053
-#define HDMI_FC_SDPPRODUCTNAME2                 0x1054
-#define HDMI_FC_SDPPRODUCTNAME3                 0x1055
-#define HDMI_FC_SDPPRODUCTNAME4                 0x1056
-#define HDMI_FC_SDPPRODUCTNAME5                 0x1057
-#define HDMI_FC_SDPPRODUCTNAME6                 0x1058
-#define HDMI_FC_SDPPRODUCTNAME7                 0x1059
-#define HDMI_FC_SDPPRODUCTNAME8                 0x105A
-#define HDMI_FC_SDPPRODUCTNAME9                 0x105B
-#define HDMI_FC_SDPPRODUCTNAME10                0x105C
-#define HDMI_FC_SDPPRODUCTNAME11                0x105D
-#define HDMI_FC_SDPPRODUCTNAME12                0x105E
-#define HDMI_FC_SDPPRODUCTNAME13                0x105F
-#define HDMI_FC_SDPPRODUCTNAME14                0x1060
-#define HDMI_FC_SPDPRODUCTNAME15                0x1061
-#define HDMI_FC_SPDDEVICEINF                    0x1062
-#define HDMI_FC_AUDSCONF                        0x1063
-#define HDMI_FC_AUDSSTAT                        0x1064
-#define HDMI_FC_DATACH0FILL                     0x1070
-#define HDMI_FC_DATACH1FILL                     0x1071
-#define HDMI_FC_DATACH2FILL                     0x1072
-#define HDMI_FC_CTRLQHIGH                       0x1073
-#define HDMI_FC_CTRLQLOW                        0x1074
-#define HDMI_FC_ACP0                            0x1075
-#define HDMI_FC_ACP28                           0x1076
-#define HDMI_FC_ACP27                           0x1077
-#define HDMI_FC_ACP26                           0x1078
-#define HDMI_FC_ACP25                           0x1079
-#define HDMI_FC_ACP24                           0x107A
-#define HDMI_FC_ACP23                           0x107B
-#define HDMI_FC_ACP22                           0x107C
-#define HDMI_FC_ACP21                           0x107D
-#define HDMI_FC_ACP20                           0x107E
-#define HDMI_FC_ACP19                           0x107F
-#define HDMI_FC_ACP18                           0x1080
-#define HDMI_FC_ACP17                           0x1081
-#define HDMI_FC_ACP16                           0x1082
-#define HDMI_FC_ACP15                           0x1083
-#define HDMI_FC_ACP14                           0x1084
-#define HDMI_FC_ACP13                           0x1085
-#define HDMI_FC_ACP12                           0x1086
-#define HDMI_FC_ACP11                           0x1087
-#define HDMI_FC_ACP10                           0x1088
-#define HDMI_FC_ACP9                            0x1089
-#define HDMI_FC_ACP8                            0x108A
-#define HDMI_FC_ACP7                            0x108B
-#define HDMI_FC_ACP6                            0x108C
-#define HDMI_FC_ACP5                            0x108D
-#define HDMI_FC_ACP4                            0x108E
-#define HDMI_FC_ACP3                            0x108F
-#define HDMI_FC_ACP2                            0x1090
-#define HDMI_FC_ACP1                            0x1091
-#define HDMI_FC_ISCR1_0                         0x1092
-#define HDMI_FC_ISCR1_16                        0x1093
-#define HDMI_FC_ISCR1_15                        0x1094
-#define HDMI_FC_ISCR1_14                        0x1095
-#define HDMI_FC_ISCR1_13                        0x1096
-#define HDMI_FC_ISCR1_12                        0x1097
-#define HDMI_FC_ISCR1_11                        0x1098
-#define HDMI_FC_ISCR1_10                        0x1099
-#define HDMI_FC_ISCR1_9                         0x109A
-#define HDMI_FC_ISCR1_8                         0x109B
-#define HDMI_FC_ISCR1_7                         0x109C
-#define HDMI_FC_ISCR1_6                         0x109D
-#define HDMI_FC_ISCR1_5                         0x109E
-#define HDMI_FC_ISCR1_4                         0x109F
-#define HDMI_FC_ISCR1_3                         0x10A0
-#define HDMI_FC_ISCR1_2                         0x10A1
-#define HDMI_FC_ISCR1_1                         0x10A2
-#define HDMI_FC_ISCR2_15                        0x10A3
-#define HDMI_FC_ISCR2_14                        0x10A4
-#define HDMI_FC_ISCR2_13                        0x10A5
-#define HDMI_FC_ISCR2_12                        0x10A6
-#define HDMI_FC_ISCR2_11                        0x10A7
-#define HDMI_FC_ISCR2_10                        0x10A8
-#define HDMI_FC_ISCR2_9                         0x10A9
-#define HDMI_FC_ISCR2_8                         0x10AA
-#define HDMI_FC_ISCR2_7                         0x10AB
-#define HDMI_FC_ISCR2_6                         0x10AC
-#define HDMI_FC_ISCR2_5                         0x10AD
-#define HDMI_FC_ISCR2_4                         0x10AE
-#define HDMI_FC_ISCR2_3                         0x10AF
-#define HDMI_FC_ISCR2_2                         0x10B0
-#define HDMI_FC_ISCR2_1                         0x10B1
-#define HDMI_FC_ISCR2_0                         0x10B2
-#define HDMI_FC_DATAUTO0                        0x10B3
-#define HDMI_FC_DATAUTO1                        0x10B4
-#define HDMI_FC_DATAUTO2                        0x10B5
-#define HDMI_FC_DATMAN                          0x10B6
-#define HDMI_FC_DATAUTO3                        0x10B7
-#define HDMI_FC_RDRB0                           0x10B8
-#define HDMI_FC_RDRB1                           0x10B9
-#define HDMI_FC_RDRB2                           0x10BA
-#define HDMI_FC_RDRB3                           0x10BB
-#define HDMI_FC_RDRB4                           0x10BC
-#define HDMI_FC_RDRB5                           0x10BD
-#define HDMI_FC_RDRB6                           0x10BE
-#define HDMI_FC_RDRB7                           0x10BF
-#define HDMI_FC_STAT0                           0x10D0
-#define HDMI_FC_INT0                            0x10D1
-#define HDMI_FC_MASK0                           0x10D2
-#define HDMI_FC_POL0                            0x10D3
-#define HDMI_FC_STAT1                           0x10D4
-#define HDMI_FC_INT1                            0x10D5
-#define HDMI_FC_MASK1                           0x10D6
-#define HDMI_FC_POL1                            0x10D7
-#define HDMI_FC_STAT2                           0x10D8
-#define HDMI_FC_INT2                            0x10D9
-#define HDMI_FC_MASK2                           0x10DA
-#define HDMI_FC_POL2                            0x10DB
-#define HDMI_FC_PRCONF                          0x10E0
-
-#define HDMI_FC_GMD_STAT                        0x1100
-#define HDMI_FC_GMD_EN                          0x1101
-#define HDMI_FC_GMD_UP                          0x1102
-#define HDMI_FC_GMD_CONF                        0x1103
-#define HDMI_FC_GMD_HB                          0x1104
-#define HDMI_FC_GMD_PB0                         0x1105
-#define HDMI_FC_GMD_PB1                         0x1106
-#define HDMI_FC_GMD_PB2                         0x1107
-#define HDMI_FC_GMD_PB3                         0x1108
-#define HDMI_FC_GMD_PB4                         0x1109
-#define HDMI_FC_GMD_PB5                         0x110A
-#define HDMI_FC_GMD_PB6                         0x110B
-#define HDMI_FC_GMD_PB7                         0x110C
-#define HDMI_FC_GMD_PB8                         0x110D
-#define HDMI_FC_GMD_PB9                         0x110E
-#define HDMI_FC_GMD_PB10                        0x110F
-#define HDMI_FC_GMD_PB11                        0x1110
-#define HDMI_FC_GMD_PB12                        0x1111
-#define HDMI_FC_GMD_PB13                        0x1112
-#define HDMI_FC_GMD_PB14                        0x1113
-#define HDMI_FC_GMD_PB15                        0x1114
-#define HDMI_FC_GMD_PB16                        0x1115
-#define HDMI_FC_GMD_PB17                        0x1116
-#define HDMI_FC_GMD_PB18                        0x1117
-#define HDMI_FC_GMD_PB19                        0x1118
-#define HDMI_FC_GMD_PB20                        0x1119
-#define HDMI_FC_GMD_PB21                        0x111A
-#define HDMI_FC_GMD_PB22                        0x111B
-#define HDMI_FC_GMD_PB23                        0x111C
-#define HDMI_FC_GMD_PB24                        0x111D
-#define HDMI_FC_GMD_PB25                        0x111E
-#define HDMI_FC_GMD_PB26                        0x111F
-#define HDMI_FC_GMD_PB27                        0x1120
-
-#define HDMI_FC_DBGFORCE                        0x1200
-#define HDMI_FC_DBGAUD0CH0                      0x1201
-#define HDMI_FC_DBGAUD1CH0                      0x1202
-#define HDMI_FC_DBGAUD2CH0                      0x1203
-#define HDMI_FC_DBGAUD0CH1                      0x1204
-#define HDMI_FC_DBGAUD1CH1                      0x1205
-#define HDMI_FC_DBGAUD2CH1                      0x1206
-#define HDMI_FC_DBGAUD0CH2                      0x1207
-#define HDMI_FC_DBGAUD1CH2                      0x1208
-#define HDMI_FC_DBGAUD2CH2                      0x1209
-#define HDMI_FC_DBGAUD0CH3                      0x120A
-#define HDMI_FC_DBGAUD1CH3                      0x120B
-#define HDMI_FC_DBGAUD2CH3                      0x120C
-#define HDMI_FC_DBGAUD0CH4                      0x120D
-#define HDMI_FC_DBGAUD1CH4                      0x120E
-#define HDMI_FC_DBGAUD2CH4                      0x120F
-#define HDMI_FC_DBGAUD0CH5                      0x1210
-#define HDMI_FC_DBGAUD1CH5                      0x1211
-#define HDMI_FC_DBGAUD2CH5                      0x1212
-#define HDMI_FC_DBGAUD0CH6                      0x1213
-#define HDMI_FC_DBGAUD1CH6                      0x1214
-#define HDMI_FC_DBGAUD2CH6                      0x1215
-#define HDMI_FC_DBGAUD0CH7                      0x1216
-#define HDMI_FC_DBGAUD1CH7                      0x1217
-#define HDMI_FC_DBGAUD2CH7                      0x1218
-#define HDMI_FC_DBGTMDS0                        0x1219
-#define HDMI_FC_DBGTMDS1                        0x121A
-#define HDMI_FC_DBGTMDS2                        0x121B
-
-/* HDMI Source PHY Registers */
-#define HDMI_PHY_CONF0                          0x3000
-#define HDMI_PHY_TST0                           0x3001
-#define HDMI_PHY_TST1                           0x3002
-#define HDMI_PHY_TST2                           0x3003
-#define HDMI_PHY_STAT0                          0x3004
-#define HDMI_PHY_INT0                           0x3005
-#define HDMI_PHY_MASK0                          0x3006
-#define HDMI_PHY_POL0                           0x3007
-
-/* HDMI Master PHY Registers */
-#define HDMI_PHY_I2CM_SLAVE_ADDR                0x3020
-#define HDMI_PHY_I2CM_ADDRESS_ADDR              0x3021
-#define HDMI_PHY_I2CM_DATAO_1_ADDR              0x3022
-#define HDMI_PHY_I2CM_DATAO_0_ADDR              0x3023
-#define HDMI_PHY_I2CM_DATAI_1_ADDR              0x3024
-#define HDMI_PHY_I2CM_DATAI_0_ADDR              0x3025
-#define HDMI_PHY_I2CM_OPERATION_ADDR            0x3026
-#define HDMI_PHY_I2CM_INT_ADDR                  0x3027
-#define HDMI_PHY_I2CM_CTLINT_ADDR               0x3028
-#define HDMI_PHY_I2CM_DIV_ADDR                  0x3029
-#define HDMI_PHY_I2CM_SOFTRSTZ_ADDR             0x302a
-#define HDMI_PHY_I2CM_SS_SCL_HCNT_1_ADDR        0x302b
-#define HDMI_PHY_I2CM_SS_SCL_HCNT_0_ADDR        0x302c
-#define HDMI_PHY_I2CM_SS_SCL_LCNT_1_ADDR        0x302d
-#define HDMI_PHY_I2CM_SS_SCL_LCNT_0_ADDR        0x302e
-#define HDMI_PHY_I2CM_FS_SCL_HCNT_1_ADDR        0x302f
-#define HDMI_PHY_I2CM_FS_SCL_HCNT_0_ADDR        0x3030
-#define HDMI_PHY_I2CM_FS_SCL_LCNT_1_ADDR        0x3031
-#define HDMI_PHY_I2CM_FS_SCL_LCNT_0_ADDR        0x3032
-
-/* Audio Sampler Registers */
-#define HDMI_AUD_CONF0                          0x3100
-#define HDMI_AUD_CONF1                          0x3101
-#define HDMI_AUD_INT                            0x3102
-#define HDMI_AUD_CONF2                          0x3103
-#define HDMI_AUD_N1                             0x3200
-#define HDMI_AUD_N2                             0x3201
-#define HDMI_AUD_N3                             0x3202
-#define HDMI_AUD_CTS1                           0x3203
-#define HDMI_AUD_CTS2                           0x3204
-#define HDMI_AUD_CTS3                           0x3205
-#define HDMI_AUD_INPUTCLKFS                     0x3206
-#define HDMI_AUD_SPDIFINT                      0x3302
-#define HDMI_AUD_CONF0_HBR                      0x3400
-#define HDMI_AUD_HBR_STATUS                     0x3401
-#define HDMI_AUD_HBR_INT                        0x3402
-#define HDMI_AUD_HBR_POL                        0x3403
-#define HDMI_AUD_HBR_MASK                       0x3404
-
-/*
- * Generic Parallel Audio Interface Registers
- * Not used as GPAUD interface is not enabled in hw
- */
-#define HDMI_GP_CONF0                           0x3500
-#define HDMI_GP_CONF1                           0x3501
-#define HDMI_GP_CONF2                           0x3502
-#define HDMI_GP_STAT                            0x3503
-#define HDMI_GP_INT                             0x3504
-#define HDMI_GP_MASK                            0x3505
-#define HDMI_GP_POL                             0x3506
-
-/* Audio DMA Registers */
-#define HDMI_AHB_DMA_CONF0                      0x3600
-#define HDMI_AHB_DMA_START                      0x3601
-#define HDMI_AHB_DMA_STOP                       0x3602
-#define HDMI_AHB_DMA_THRSLD                     0x3603
-#define HDMI_AHB_DMA_STRADDR0                   0x3604
-#define HDMI_AHB_DMA_STRADDR1                   0x3605
-#define HDMI_AHB_DMA_STRADDR2                   0x3606
-#define HDMI_AHB_DMA_STRADDR3                   0x3607
-#define HDMI_AHB_DMA_STPADDR0                   0x3608
-#define HDMI_AHB_DMA_STPADDR1                   0x3609
-#define HDMI_AHB_DMA_STPADDR2                   0x360a
-#define HDMI_AHB_DMA_STPADDR3                   0x360b
-#define HDMI_AHB_DMA_BSTADDR0                   0x360c
-#define HDMI_AHB_DMA_BSTADDR1                   0x360d
-#define HDMI_AHB_DMA_BSTADDR2                   0x360e
-#define HDMI_AHB_DMA_BSTADDR3                   0x360f
-#define HDMI_AHB_DMA_MBLENGTH0                  0x3610
-#define HDMI_AHB_DMA_MBLENGTH1                  0x3611
-#define HDMI_AHB_DMA_STAT                       0x3612
-#define HDMI_AHB_DMA_INT                        0x3613
-#define HDMI_AHB_DMA_MASK                       0x3614
-#define HDMI_AHB_DMA_POL                        0x3615
-#define HDMI_AHB_DMA_CONF1                      0x3616
-#define HDMI_AHB_DMA_BUFFSTAT                   0x3617
-#define HDMI_AHB_DMA_BUFFINT                    0x3618
-#define HDMI_AHB_DMA_BUFFMASK                   0x3619
-#define HDMI_AHB_DMA_BUFFPOL                    0x361a
-
-/* Main Controller Registers */
-#define HDMI_MC_SFRDIV                          0x4000
-#define HDMI_MC_CLKDIS                          0x4001
-#define HDMI_MC_SWRSTZ                          0x4002
-#define HDMI_MC_OPCTRL                          0x4003
-#define HDMI_MC_FLOWCTRL                        0x4004
-#define HDMI_MC_PHYRSTZ                         0x4005
-#define HDMI_MC_LOCKONCLOCK                     0x4006
-#define HDMI_MC_HEACPHY_RST                     0x4007
-
-/* Color Space  Converter Registers */
-#define HDMI_CSC_CFG                            0x4100
-#define HDMI_CSC_SCALE                          0x4101
-#define HDMI_CSC_COEF_A1_MSB                    0x4102
-#define HDMI_CSC_COEF_A1_LSB                    0x4103
-#define HDMI_CSC_COEF_A2_MSB                    0x4104
-#define HDMI_CSC_COEF_A2_LSB                    0x4105
-#define HDMI_CSC_COEF_A3_MSB                    0x4106
-#define HDMI_CSC_COEF_A3_LSB                    0x4107
-#define HDMI_CSC_COEF_A4_MSB                    0x4108
-#define HDMI_CSC_COEF_A4_LSB                    0x4109
-#define HDMI_CSC_COEF_B1_MSB                    0x410A
-#define HDMI_CSC_COEF_B1_LSB                    0x410B
-#define HDMI_CSC_COEF_B2_MSB                    0x410C
-#define HDMI_CSC_COEF_B2_LSB                    0x410D
-#define HDMI_CSC_COEF_B3_MSB                    0x410E
-#define HDMI_CSC_COEF_B3_LSB                    0x410F
-#define HDMI_CSC_COEF_B4_MSB                    0x4110
-#define HDMI_CSC_COEF_B4_LSB                    0x4111
-#define HDMI_CSC_COEF_C1_MSB                    0x4112
-#define HDMI_CSC_COEF_C1_LSB                    0x4113
-#define HDMI_CSC_COEF_C2_MSB                    0x4114
-#define HDMI_CSC_COEF_C2_LSB                    0x4115
-#define HDMI_CSC_COEF_C3_MSB                    0x4116
-#define HDMI_CSC_COEF_C3_LSB                    0x4117
-#define HDMI_CSC_COEF_C4_MSB                    0x4118
-#define HDMI_CSC_COEF_C4_LSB                    0x4119
-
-/* HDCP Encryption Engine Registers */
-#define HDMI_A_HDCPCFG0                         0x5000
-#define HDMI_A_HDCPCFG1                         0x5001
-#define HDMI_A_HDCPOBS0                         0x5002
-#define HDMI_A_HDCPOBS1                         0x5003
-#define HDMI_A_HDCPOBS2                         0x5004
-#define HDMI_A_HDCPOBS3                         0x5005
-#define HDMI_A_APIINTCLR                        0x5006
-#define HDMI_A_APIINTSTAT                       0x5007
-#define HDMI_A_APIINTMSK                        0x5008
-#define HDMI_A_VIDPOLCFG                        0x5009
-#define HDMI_A_OESSWCFG                         0x500A
-#define HDMI_A_TIMER1SETUP0                     0x500B
-#define HDMI_A_TIMER1SETUP1                     0x500C
-#define HDMI_A_TIMER2SETUP0                     0x500D
-#define HDMI_A_TIMER2SETUP1                     0x500E
-#define HDMI_A_100MSCFG                         0x500F
-#define HDMI_A_2SCFG0                           0x5010
-#define HDMI_A_2SCFG1                           0x5011
-#define HDMI_A_5SCFG0                           0x5012
-#define HDMI_A_5SCFG1                           0x5013
-#define HDMI_A_SRMVERLSB                        0x5014
-#define HDMI_A_SRMVERMSB                        0x5015
-#define HDMI_A_SRMCTRL                          0x5016
-#define HDMI_A_SFRSETUP                         0x5017
-#define HDMI_A_I2CHSETUP                        0x5018
-#define HDMI_A_INTSETUP                         0x5019
-#define HDMI_A_PRESETUP                         0x501A
-#define HDMI_A_SRM_BASE                         0x5020
-
-/* CEC Engine Registers */
-#define HDMI_CEC_CTRL                           0x7D00
-#define HDMI_CEC_STAT                           0x7D01
-#define HDMI_CEC_MASK                           0x7D02
-#define HDMI_CEC_POLARITY                       0x7D03
-#define HDMI_CEC_INT                            0x7D04
-#define HDMI_CEC_ADDR_L                         0x7D05
-#define HDMI_CEC_ADDR_H                         0x7D06
-#define HDMI_CEC_TX_CNT                         0x7D07
-#define HDMI_CEC_RX_CNT                         0x7D08
-#define HDMI_CEC_TX_DATA0                       0x7D10
-#define HDMI_CEC_TX_DATA1                       0x7D11
-#define HDMI_CEC_TX_DATA2                       0x7D12
-#define HDMI_CEC_TX_DATA3                       0x7D13
-#define HDMI_CEC_TX_DATA4                       0x7D14
-#define HDMI_CEC_TX_DATA5                       0x7D15
-#define HDMI_CEC_TX_DATA6                       0x7D16
-#define HDMI_CEC_TX_DATA7                       0x7D17
-#define HDMI_CEC_TX_DATA8                       0x7D18
-#define HDMI_CEC_TX_DATA9                       0x7D19
-#define HDMI_CEC_TX_DATA10                      0x7D1a
-#define HDMI_CEC_TX_DATA11                      0x7D1b
-#define HDMI_CEC_TX_DATA12                      0x7D1c
-#define HDMI_CEC_TX_DATA13                      0x7D1d
-#define HDMI_CEC_TX_DATA14                      0x7D1e
-#define HDMI_CEC_TX_DATA15                      0x7D1f
-#define HDMI_CEC_RX_DATA0                       0x7D20
-#define HDMI_CEC_RX_DATA1                       0x7D21
-#define HDMI_CEC_RX_DATA2                       0x7D22
-#define HDMI_CEC_RX_DATA3                       0x7D23
-#define HDMI_CEC_RX_DATA4                       0x7D24
-#define HDMI_CEC_RX_DATA5                       0x7D25
-#define HDMI_CEC_RX_DATA6                       0x7D26
-#define HDMI_CEC_RX_DATA7                       0x7D27
-#define HDMI_CEC_RX_DATA8                       0x7D28
-#define HDMI_CEC_RX_DATA9                       0x7D29
-#define HDMI_CEC_RX_DATA10                      0x7D2a
-#define HDMI_CEC_RX_DATA11                      0x7D2b
-#define HDMI_CEC_RX_DATA12                      0x7D2c
-#define HDMI_CEC_RX_DATA13                      0x7D2d
-#define HDMI_CEC_RX_DATA14                      0x7D2e
-#define HDMI_CEC_RX_DATA15                      0x7D2f
-#define HDMI_CEC_LOCK                           0x7D30
-#define HDMI_CEC_WKUPCTRL                       0x7D31
-
-/* I2C Master Registers (E-DDC) */
-#define HDMI_I2CM_SLAVE                         0x7E00
-#define HDMI_I2CMESS                            0x7E01
-#define HDMI_I2CM_DATAO                         0x7E02
-#define HDMI_I2CM_DATAI                         0x7E03
-#define HDMI_I2CM_OPERATION                     0x7E04
-#define HDMI_I2CM_INT                           0x7E05
-#define HDMI_I2CM_CTLINT                        0x7E06
-#define HDMI_I2CM_DIV                           0x7E07
-#define HDMI_I2CM_SEGADDR                       0x7E08
-#define HDMI_I2CM_SOFTRSTZ                      0x7E09
-#define HDMI_I2CM_SEGPTR                        0x7E0A
-#define HDMI_I2CM_SS_SCL_HCNT_1_ADDR            0x7E0B
-#define HDMI_I2CM_SS_SCL_HCNT_0_ADDR            0x7E0C
-#define HDMI_I2CM_SS_SCL_LCNT_1_ADDR            0x7E0D
-#define HDMI_I2CM_SS_SCL_LCNT_0_ADDR            0x7E0E
-#define HDMI_I2CM_FS_SCL_HCNT_1_ADDR            0x7E0F
-#define HDMI_I2CM_FS_SCL_HCNT_0_ADDR            0x7E10
-#define HDMI_I2CM_FS_SCL_LCNT_1_ADDR            0x7E11
-#define HDMI_I2CM_FS_SCL_LCNT_0_ADDR            0x7E12
-
-enum {
-/* IH_FC_INT2 field values */
-       HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03,
-       HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
-       HDMI_IH_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01,
-
-/* IH_FC_STAT2 field values */
-       HDMI_IH_FC_STAT2_OVERFLOW_MASK = 0x03,
-       HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
-       HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
-
-/* IH_PHY_STAT0 field values */
-       HDMI_IH_PHY_STAT0_RX_SENSE3 = 0x20,
-       HDMI_IH_PHY_STAT0_RX_SENSE2 = 0x10,
-       HDMI_IH_PHY_STAT0_RX_SENSE1 = 0x8,
-       HDMI_IH_PHY_STAT0_RX_SENSE0 = 0x4,
-       HDMI_IH_PHY_STAT0_TX_PHY_LOCK = 0x2,
-       HDMI_IH_PHY_STAT0_HPD = 0x1,
-
-/* IH_MUTE_I2CMPHY_STAT0 field values */
-       HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYDONE = 0x2,
-       HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYERROR = 0x1,
-
-/* IH_AHBDMAAUD_STAT0 field values */
-       HDMI_IH_AHBDMAAUD_STAT0_ERROR = 0x20,
-       HDMI_IH_AHBDMAAUD_STAT0_LOST = 0x10,
-       HDMI_IH_AHBDMAAUD_STAT0_RETRY = 0x08,
-       HDMI_IH_AHBDMAAUD_STAT0_DONE = 0x04,
-       HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = 0x02,
-       HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01,
-
-/* IH_MUTE_FC_STAT2 field values */
-       HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK = 0x03,
-       HDMI_IH_MUTE_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
-       HDMI_IH_MUTE_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
-
-/* IH_MUTE_AHBDMAAUD_STAT0 field values */
-       HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = 0x20,
-       HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = 0x10,
-       HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = 0x08,
-       HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = 0x04,
-       HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = 0x02,
-       HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01,
-
-/* IH_MUTE field values */
-       HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT = 0x2,
-       HDMI_IH_MUTE_MUTE_ALL_INTERRUPT = 0x1,
-
-/* TX_INVID0 field values */
-       HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_MASK = 0x80,
-       HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_ENABLE = 0x80,
-       HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE = 0x00,
-       HDMI_TX_INVID0_VIDEO_MAPPING_MASK = 0x1F,
-       HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET = 0,
-
-/* TX_INSTUFFING field values */
-       HDMI_TX_INSTUFFING_BDBDATA_STUFFING_MASK = 0x4,
-       HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE = 0x4,
-       HDMI_TX_INSTUFFING_BDBDATA_STUFFING_DISABLE = 0x0,
-       HDMI_TX_INSTUFFING_RCRDATA_STUFFING_MASK = 0x2,
-       HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE = 0x2,
-       HDMI_TX_INSTUFFING_RCRDATA_STUFFING_DISABLE = 0x0,
-       HDMI_TX_INSTUFFING_GYDATA_STUFFING_MASK = 0x1,
-       HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE = 0x1,
-       HDMI_TX_INSTUFFING_GYDATA_STUFFING_DISABLE = 0x0,
-
-/* VP_PR_CD field values */
-       HDMI_VP_PR_CD_COLOR_DEPTH_MASK = 0xF0,
-       HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET = 4,
-       HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK = 0x0F,
-       HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET = 0,
-
-/* VP_STUFF field values */
-       HDMI_VP_STUFF_IDEFAULT_PHASE_MASK = 0x20,
-       HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET = 5,
-       HDMI_VP_STUFF_IFIX_PP_TO_LAST_MASK = 0x10,
-       HDMI_VP_STUFF_IFIX_PP_TO_LAST_OFFSET = 4,
-       HDMI_VP_STUFF_ICX_GOTO_P0_ST_MASK = 0x8,
-       HDMI_VP_STUFF_ICX_GOTO_P0_ST_OFFSET = 3,
-       HDMI_VP_STUFF_YCC422_STUFFING_MASK = 0x4,
-       HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE = 0x4,
-       HDMI_VP_STUFF_YCC422_STUFFING_DIRECT_MODE = 0x0,
-       HDMI_VP_STUFF_PP_STUFFING_MASK = 0x2,
-       HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE = 0x2,
-       HDMI_VP_STUFF_PP_STUFFING_DIRECT_MODE = 0x0,
-       HDMI_VP_STUFF_PR_STUFFING_MASK = 0x1,
-       HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE = 0x1,
-       HDMI_VP_STUFF_PR_STUFFING_DIRECT_MODE = 0x0,
-
-/* VP_CONF field values */
-       HDMI_VP_CONF_BYPASS_EN_MASK = 0x40,
-       HDMI_VP_CONF_BYPASS_EN_ENABLE = 0x40,
-       HDMI_VP_CONF_BYPASS_EN_DISABLE = 0x00,
-       HDMI_VP_CONF_PP_EN_ENMASK = 0x20,
-       HDMI_VP_CONF_PP_EN_ENABLE = 0x20,
-       HDMI_VP_CONF_PP_EN_DISABLE = 0x00,
-       HDMI_VP_CONF_PR_EN_MASK = 0x10,
-       HDMI_VP_CONF_PR_EN_ENABLE = 0x10,
-       HDMI_VP_CONF_PR_EN_DISABLE = 0x00,
-       HDMI_VP_CONF_YCC422_EN_MASK = 0x8,
-       HDMI_VP_CONF_YCC422_EN_ENABLE = 0x8,
-       HDMI_VP_CONF_YCC422_EN_DISABLE = 0x0,
-       HDMI_VP_CONF_BYPASS_SELECT_MASK = 0x4,
-       HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER = 0x4,
-       HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER = 0x0,
-       HDMI_VP_CONF_OUTPUT_SELECTOR_MASK = 0x3,
-       HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS = 0x3,
-       HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422 = 0x1,
-       HDMI_VP_CONF_OUTPUT_SELECTOR_PP = 0x0,
-
-/* VP_REMAP field values */
-       HDMI_VP_REMAP_MASK = 0x3,
-       HDMI_VP_REMAP_YCC422_24bit = 0x2,
-       HDMI_VP_REMAP_YCC422_20bit = 0x1,
-       HDMI_VP_REMAP_YCC422_16bit = 0x0,
-
-/* FC_INVIDCONF field values */
-       HDMI_FC_INVIDCONF_HDCP_KEEPOUT_MASK = 0x80,
-       HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE = 0x80,
-       HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE = 0x00,
-       HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_MASK = 0x40,
-       HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH = 0x40,
-       HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW = 0x00,
-       HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_MASK = 0x20,
-       HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH = 0x20,
-       HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW = 0x00,
-       HDMI_FC_INVIDCONF_DE_IN_POLARITY_MASK = 0x10,
-       HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH = 0x10,
-       HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW = 0x00,
-       HDMI_FC_INVIDCONF_DVI_MODEZ_MASK = 0x8,
-       HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE = 0x8,
-       HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE = 0x0,
-       HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_MASK = 0x2,
-       HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH = 0x2,
-       HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW = 0x0,
-       HDMI_FC_INVIDCONF_IN_I_P_MASK = 0x1,
-       HDMI_FC_INVIDCONF_IN_I_P_INTERLACED = 0x1,
-       HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE = 0x0,
-
-/* FC_AUDICONF0 field values */
-       HDMI_FC_AUDICONF0_CC_OFFSET = 4,
-       HDMI_FC_AUDICONF0_CC_MASK = 0x70,
-       HDMI_FC_AUDICONF0_CT_OFFSET = 0,
-       HDMI_FC_AUDICONF0_CT_MASK = 0xF,
-
-/* FC_AUDICONF1 field values */
-       HDMI_FC_AUDICONF1_SS_OFFSET = 3,
-       HDMI_FC_AUDICONF1_SS_MASK = 0x18,
-       HDMI_FC_AUDICONF1_SF_OFFSET = 0,
-       HDMI_FC_AUDICONF1_SF_MASK = 0x7,
-
-/* FC_AUDICONF3 field values */
-       HDMI_FC_AUDICONF3_LFEPBL_OFFSET = 5,
-       HDMI_FC_AUDICONF3_LFEPBL_MASK = 0x60,
-       HDMI_FC_AUDICONF3_DM_INH_OFFSET = 4,
-       HDMI_FC_AUDICONF3_DM_INH_MASK = 0x10,
-       HDMI_FC_AUDICONF3_LSV_OFFSET = 0,
-       HDMI_FC_AUDICONF3_LSV_MASK = 0xF,
-
-/* FC_AUDSCHNLS0 field values */
-       HDMI_FC_AUDSCHNLS0_CGMSA_OFFSET = 4,
-       HDMI_FC_AUDSCHNLS0_CGMSA_MASK = 0x30,
-       HDMI_FC_AUDSCHNLS0_COPYRIGHT_OFFSET = 0,
-       HDMI_FC_AUDSCHNLS0_COPYRIGHT_MASK = 0x01,
-
-/* FC_AUDSCHNLS3-6 field values */
-       HDMI_FC_AUDSCHNLS3_OIEC_CH0_OFFSET = 0,
-       HDMI_FC_AUDSCHNLS3_OIEC_CH0_MASK = 0x0f,
-       HDMI_FC_AUDSCHNLS3_OIEC_CH1_OFFSET = 4,
-       HDMI_FC_AUDSCHNLS3_OIEC_CH1_MASK = 0xf0,
-       HDMI_FC_AUDSCHNLS4_OIEC_CH2_OFFSET = 0,
-       HDMI_FC_AUDSCHNLS4_OIEC_CH2_MASK = 0x0f,
-       HDMI_FC_AUDSCHNLS4_OIEC_CH3_OFFSET = 4,
-       HDMI_FC_AUDSCHNLS4_OIEC_CH3_MASK = 0xf0,
-
-       HDMI_FC_AUDSCHNLS5_OIEC_CH0_OFFSET = 0,
-       HDMI_FC_AUDSCHNLS5_OIEC_CH0_MASK = 0x0f,
-       HDMI_FC_AUDSCHNLS5_OIEC_CH1_OFFSET = 4,
-       HDMI_FC_AUDSCHNLS5_OIEC_CH1_MASK = 0xf0,
-       HDMI_FC_AUDSCHNLS6_OIEC_CH2_OFFSET = 0,
-       HDMI_FC_AUDSCHNLS6_OIEC_CH2_MASK = 0x0f,
-       HDMI_FC_AUDSCHNLS6_OIEC_CH3_OFFSET = 4,
-       HDMI_FC_AUDSCHNLS6_OIEC_CH3_MASK = 0xf0,
-
-/* HDMI_FC_AUDSCHNLS7 field values */
-       HDMI_FC_AUDSCHNLS7_ACCURACY_OFFSET = 4,
-       HDMI_FC_AUDSCHNLS7_ACCURACY_MASK = 0x30,
-
-/* HDMI_FC_AUDSCHNLS8 field values */
-       HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_MASK = 0xf0,
-       HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_OFFSET = 4,
-       HDMI_FC_AUDSCHNLS8_WORDLEGNTH_MASK = 0x0f,
-       HDMI_FC_AUDSCHNLS8_WORDLEGNTH_OFFSET = 0,
-
-/* FC_AUDSCONF field values */
-       HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_MASK = 0xF0,
-       HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_OFFSET = 4,
-       HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK = 0x1,
-       HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_OFFSET = 0,
-       HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT1 = 0x1,
-       HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT0 = 0x0,
-
-/* FC_STAT2 field values */
-       HDMI_FC_STAT2_OVERFLOW_MASK = 0x03,
-       HDMI_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02,
-       HDMI_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01,
-
-/* FC_INT2 field values */
-       HDMI_FC_INT2_OVERFLOW_MASK = 0x03,
-       HDMI_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02,
-       HDMI_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01,
-
-/* FC_MASK2 field values */
-       HDMI_FC_MASK2_OVERFLOW_MASK = 0x03,
-       HDMI_FC_MASK2_LOW_PRIORITY_OVERFLOW = 0x02,
-       HDMI_FC_MASK2_HIGH_PRIORITY_OVERFLOW = 0x01,
-
-/* FC_PRCONF field values */
-       HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK = 0xF0,
-       HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET = 4,
-       HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK = 0x0F,
-       HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET = 0,
-
-/* FC_AVICONF0-FC_AVICONF3 field values */
-       HDMI_FC_AVICONF0_PIX_FMT_MASK = 0x03,
-       HDMI_FC_AVICONF0_PIX_FMT_RGB = 0x00,
-       HDMI_FC_AVICONF0_PIX_FMT_YCBCR422 = 0x01,
-       HDMI_FC_AVICONF0_PIX_FMT_YCBCR444 = 0x02,
-       HDMI_FC_AVICONF0_ACTIVE_FMT_MASK = 0x40,
-       HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT = 0x40,
-       HDMI_FC_AVICONF0_ACTIVE_FMT_NO_INFO = 0x00,
-       HDMI_FC_AVICONF0_BAR_DATA_MASK = 0x0C,
-       HDMI_FC_AVICONF0_BAR_DATA_NO_DATA = 0x00,
-       HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR = 0x04,
-       HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR = 0x08,
-       HDMI_FC_AVICONF0_BAR_DATA_VERT_HORIZ_BAR = 0x0C,
-       HDMI_FC_AVICONF0_SCAN_INFO_MASK = 0x30,
-       HDMI_FC_AVICONF0_SCAN_INFO_OVERSCAN = 0x10,
-       HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN = 0x20,
-       HDMI_FC_AVICONF0_SCAN_INFO_NODATA = 0x00,
-
-       HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_MASK = 0x0F,
-       HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_USE_CODED = 0x08,
-       HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3 = 0x09,
-       HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9 = 0x0A,
-       HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_14_9 = 0x0B,
-       HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_MASK = 0x30,
-       HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_NO_DATA = 0x00,
-       HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3 = 0x10,
-       HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9 = 0x20,
-       HDMI_FC_AVICONF1_COLORIMETRY_MASK = 0xC0,
-       HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA = 0x00,
-       HDMI_FC_AVICONF1_COLORIMETRY_SMPTE = 0x40,
-       HDMI_FC_AVICONF1_COLORIMETRY_ITUR = 0x80,
-       HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO = 0xC0,
-
-       HDMI_FC_AVICONF2_SCALING_MASK = 0x03,
-       HDMI_FC_AVICONF2_SCALING_NONE = 0x00,
-       HDMI_FC_AVICONF2_SCALING_HORIZ = 0x01,
-       HDMI_FC_AVICONF2_SCALING_VERT = 0x02,
-       HDMI_FC_AVICONF2_SCALING_HORIZ_VERT = 0x03,
-       HDMI_FC_AVICONF2_RGB_QUANT_MASK = 0x0C,
-       HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT = 0x00,
-       HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE = 0x04,
-       HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE = 0x08,
-       HDMI_FC_AVICONF2_EXT_COLORIMETRY_MASK = 0x70,
-       HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601 = 0x00,
-       HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709 = 0x10,
-       HDMI_FC_AVICONF2_EXT_COLORIMETRY_SYCC601 = 0x20,
-       HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_YCC601 = 0x30,
-       HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_RGB = 0x40,
-       HDMI_FC_AVICONF2_IT_CONTENT_MASK = 0x80,
-       HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA = 0x00,
-       HDMI_FC_AVICONF2_IT_CONTENT_VALID = 0x80,
-
-       HDMI_FC_AVICONF3_IT_CONTENT_TYPE_MASK = 0x03,
-       HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS = 0x00,
-       HDMI_FC_AVICONF3_IT_CONTENT_TYPE_PHOTO = 0x01,
-       HDMI_FC_AVICONF3_IT_CONTENT_TYPE_CINEMA = 0x02,
-       HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GAME = 0x03,
-       HDMI_FC_AVICONF3_QUANT_RANGE_MASK = 0x0C,
-       HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED = 0x00,
-       HDMI_FC_AVICONF3_QUANT_RANGE_FULL = 0x04,
-
-/* FC_DBGFORCE field values */
-       HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10,
-       HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1,
-
-/* PHY_CONF0 field values */
-       HDMI_PHY_CONF0_PDZ_MASK = 0x80,
-       HDMI_PHY_CONF0_PDZ_OFFSET = 7,
-       HDMI_PHY_CONF0_ENTMDS_MASK = 0x40,
-       HDMI_PHY_CONF0_ENTMDS_OFFSET = 6,
-       HDMI_PHY_CONF0_SPARECTRL = 0x20,
-       HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10,
-       HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4,
-       HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8,
-       HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET = 3,
-       HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK = 0x4,
-       HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET = 2,
-       HDMI_PHY_CONF0_SELDATAENPOL_MASK = 0x2,
-       HDMI_PHY_CONF0_SELDATAENPOL_OFFSET = 1,
-       HDMI_PHY_CONF0_SELDIPIF_MASK = 0x1,
-       HDMI_PHY_CONF0_SELDIPIF_OFFSET = 0,
-
-/* PHY_TST0 field values */
-       HDMI_PHY_TST0_TSTCLR_MASK = 0x20,
-       HDMI_PHY_TST0_TSTCLR_OFFSET = 5,
-       HDMI_PHY_TST0_TSTEN_MASK = 0x10,
-       HDMI_PHY_TST0_TSTEN_OFFSET = 4,
-       HDMI_PHY_TST0_TSTCLK_MASK = 0x1,
-       HDMI_PHY_TST0_TSTCLK_OFFSET = 0,
-
-/* PHY_STAT0 field values */
-       HDMI_PHY_RX_SENSE3 = 0x80,
-       HDMI_PHY_RX_SENSE2 = 0x40,
-       HDMI_PHY_RX_SENSE1 = 0x20,
-       HDMI_PHY_RX_SENSE0 = 0x10,
-       HDMI_PHY_HPD = 0x02,
-       HDMI_PHY_TX_PHY_LOCK = 0x01,
-
-/* PHY_I2CM_SLAVE_ADDR field values */
-       HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2 = 0x69,
-       HDMI_PHY_I2CM_SLAVE_ADDR_HEAC_PHY = 0x49,
-
-/* PHY_I2CM_OPERATION_ADDR field values */
-       HDMI_PHY_I2CM_OPERATION_ADDR_WRITE = 0x10,
-       HDMI_PHY_I2CM_OPERATION_ADDR_READ = 0x1,
-
-/* HDMI_PHY_I2CM_INT_ADDR */
-       HDMI_PHY_I2CM_INT_ADDR_DONE_POL = 0x08,
-       HDMI_PHY_I2CM_INT_ADDR_DONE_MASK = 0x04,
-
-/* HDMI_PHY_I2CM_CTLINT_ADDR */
-       HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL = 0x80,
-       HDMI_PHY_I2CM_CTLINT_ADDR_NAC_MASK = 0x40,
-       HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL = 0x08,
-       HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_MASK = 0x04,
-
-/* AUD_CTS3 field values */
-       HDMI_AUD_CTS3_N_SHIFT_OFFSET = 5,
-       HDMI_AUD_CTS3_N_SHIFT_MASK = 0xe0,
-       HDMI_AUD_CTS3_N_SHIFT_1 = 0,
-       HDMI_AUD_CTS3_N_SHIFT_16 = 0x20,
-       HDMI_AUD_CTS3_N_SHIFT_32 = 0x40,
-       HDMI_AUD_CTS3_N_SHIFT_64 = 0x60,
-       HDMI_AUD_CTS3_N_SHIFT_128 = 0x80,
-       HDMI_AUD_CTS3_N_SHIFT_256 = 0xa0,
-       /* note that the CTS3 MANUAL bit has been removed
-          from our part. Can't set it, will read as 0. */
-       HDMI_AUD_CTS3_CTS_MANUAL = 0x10,
-       HDMI_AUD_CTS3_AUDCTS19_16_MASK = 0x0f,
-
-/* AHB_DMA_CONF0 field values */
-       HDMI_AHB_DMA_CONF0_SW_FIFO_RST_OFFSET = 7,
-       HDMI_AHB_DMA_CONF0_SW_FIFO_RST_MASK = 0x80,
-       HDMI_AHB_DMA_CONF0_HBR = 0x10,
-       HDMI_AHB_DMA_CONF0_EN_HLOCK_OFFSET = 3,
-       HDMI_AHB_DMA_CONF0_EN_HLOCK_MASK = 0x08,
-       HDMI_AHB_DMA_CONF0_INCR_TYPE_OFFSET = 1,
-       HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK = 0x06,
-       HDMI_AHB_DMA_CONF0_INCR4 = 0x0,
-       HDMI_AHB_DMA_CONF0_INCR8 = 0x2,
-       HDMI_AHB_DMA_CONF0_INCR16 = 0x4,
-       HDMI_AHB_DMA_CONF0_BURST_MODE = 0x1,
-
-/* HDMI_AHB_DMA_START field values */
-       HDMI_AHB_DMA_START_START_OFFSET = 0,
-       HDMI_AHB_DMA_START_START_MASK = 0x01,
-
-/* HDMI_AHB_DMA_STOP field values */
-       HDMI_AHB_DMA_STOP_STOP_OFFSET = 0,
-       HDMI_AHB_DMA_STOP_STOP_MASK = 0x01,
-
-/* AHB_DMA_STAT, AHB_DMA_INT, AHB_DMA_MASK, AHB_DMA_POL field values */
-       HDMI_AHB_DMA_DONE = 0x80,
-       HDMI_AHB_DMA_RETRY_SPLIT = 0x40,
-       HDMI_AHB_DMA_LOSTOWNERSHIP = 0x20,
-       HDMI_AHB_DMA_ERROR = 0x10,
-       HDMI_AHB_DMA_FIFO_THREMPTY = 0x04,
-       HDMI_AHB_DMA_FIFO_FULL = 0x02,
-       HDMI_AHB_DMA_FIFO_EMPTY = 0x01,
-
-/* AHB_DMA_BUFFSTAT, AHB_DMA_BUFFINT,AHB_DMA_BUFFMASK,AHB_DMA_BUFFPOL values */
-       HDMI_AHB_DMA_BUFFSTAT_FULL = 0x02,
-       HDMI_AHB_DMA_BUFFSTAT_EMPTY = 0x01,
-
-/* MC_CLKDIS field values */
-       HDMI_MC_CLKDIS_HDCPCLK_DISABLE = 0x40,
-       HDMI_MC_CLKDIS_CECCLK_DISABLE = 0x20,
-       HDMI_MC_CLKDIS_CSCCLK_DISABLE = 0x10,
-       HDMI_MC_CLKDIS_AUDCLK_DISABLE = 0x8,
-       HDMI_MC_CLKDIS_PREPCLK_DISABLE = 0x4,
-       HDMI_MC_CLKDIS_TMDSCLK_DISABLE = 0x2,
-       HDMI_MC_CLKDIS_PIXELCLK_DISABLE = 0x1,
-
-/* MC_SWRSTZ field values */
-       HDMI_MC_SWRSTZ_TMDSSWRST_REQ = 0x02,
-
-/* MC_FLOWCTRL field values */
-       HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_MASK = 0x1,
-       HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH = 0x1,
-       HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS = 0x0,
-
-/* MC_PHYRSTZ field values */
-       HDMI_MC_PHYRSTZ_ASSERT = 0x0,
-       HDMI_MC_PHYRSTZ_DEASSERT = 0x1,
-
-/* MC_HEACPHY_RST field values */
-       HDMI_MC_HEACPHY_RST_ASSERT = 0x1,
-       HDMI_MC_HEACPHY_RST_DEASSERT = 0x0,
-
-/* CSC_CFG field values */
-       HDMI_CSC_CFG_INTMODE_MASK = 0x30,
-       HDMI_CSC_CFG_INTMODE_OFFSET = 4,
-       HDMI_CSC_CFG_INTMODE_DISABLE = 0x00,
-       HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1 = 0x10,
-       HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA2 = 0x20,
-       HDMI_CSC_CFG_DECMODE_MASK = 0x3,
-       HDMI_CSC_CFG_DECMODE_OFFSET = 0,
-       HDMI_CSC_CFG_DECMODE_DISABLE = 0x0,
-       HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA1 = 0x1,
-       HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA2 = 0x2,
-       HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3 = 0x3,
-
-/* CSC_SCALE field values */
-       HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK = 0xF0,
-       HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP = 0x00,
-       HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP = 0x50,
-       HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP = 0x60,
-       HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP = 0x70,
-       HDMI_CSC_SCALE_CSCSCALE_MASK = 0x03,
-
-/* A_HDCPCFG0 field values */
-       HDMI_A_HDCPCFG0_ELVENA_MASK = 0x80,
-       HDMI_A_HDCPCFG0_ELVENA_ENABLE = 0x80,
-       HDMI_A_HDCPCFG0_ELVENA_DISABLE = 0x00,
-       HDMI_A_HDCPCFG0_I2CFASTMODE_MASK = 0x40,
-       HDMI_A_HDCPCFG0_I2CFASTMODE_ENABLE = 0x40,
-       HDMI_A_HDCPCFG0_I2CFASTMODE_DISABLE = 0x00,
-       HDMI_A_HDCPCFG0_BYPENCRYPTION_MASK = 0x20,
-       HDMI_A_HDCPCFG0_BYPENCRYPTION_ENABLE = 0x20,
-       HDMI_A_HDCPCFG0_BYPENCRYPTION_DISABLE = 0x00,
-       HDMI_A_HDCPCFG0_SYNCRICHECK_MASK = 0x10,
-       HDMI_A_HDCPCFG0_SYNCRICHECK_ENABLE = 0x10,
-       HDMI_A_HDCPCFG0_SYNCRICHECK_DISABLE = 0x00,
-       HDMI_A_HDCPCFG0_AVMUTE_MASK = 0x8,
-       HDMI_A_HDCPCFG0_AVMUTE_ENABLE = 0x8,
-       HDMI_A_HDCPCFG0_AVMUTE_DISABLE = 0x0,
-       HDMI_A_HDCPCFG0_RXDETECT_MASK = 0x4,
-       HDMI_A_HDCPCFG0_RXDETECT_ENABLE = 0x4,
-       HDMI_A_HDCPCFG0_RXDETECT_DISABLE = 0x0,
-       HDMI_A_HDCPCFG0_EN11FEATURE_MASK = 0x2,
-       HDMI_A_HDCPCFG0_EN11FEATURE_ENABLE = 0x2,
-       HDMI_A_HDCPCFG0_EN11FEATURE_DISABLE = 0x0,
-       HDMI_A_HDCPCFG0_HDMIDVI_MASK = 0x1,
-       HDMI_A_HDCPCFG0_HDMIDVI_HDMI = 0x1,
-       HDMI_A_HDCPCFG0_HDMIDVI_DVI = 0x0,
-
-/* A_HDCPCFG1 field values */
-       HDMI_A_HDCPCFG1_DISSHA1CHECK_MASK = 0x8,
-       HDMI_A_HDCPCFG1_DISSHA1CHECK_DISABLE = 0x8,
-       HDMI_A_HDCPCFG1_DISSHA1CHECK_ENABLE = 0x0,
-       HDMI_A_HDCPCFG1_PH2UPSHFTENC_MASK = 0x4,
-       HDMI_A_HDCPCFG1_PH2UPSHFTENC_ENABLE = 0x4,
-       HDMI_A_HDCPCFG1_PH2UPSHFTENC_DISABLE = 0x0,
-       HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK = 0x2,
-       HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE = 0x2,
-       HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_ENABLE = 0x0,
-       HDMI_A_HDCPCFG1_SWRESET_MASK = 0x1,
-       HDMI_A_HDCPCFG1_SWRESET_ASSERT = 0x0,
-
-/* A_VIDPOLCFG field values */
-       HDMI_A_VIDPOLCFG_UNENCRYPTCONF_MASK = 0x60,
-       HDMI_A_VIDPOLCFG_UNENCRYPTCONF_OFFSET = 5,
-       HDMI_A_VIDPOLCFG_DATAENPOL_MASK = 0x10,
-       HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH = 0x10,
-       HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW = 0x0,
-       HDMI_A_VIDPOLCFG_VSYNCPOL_MASK = 0x8,
-       HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_HIGH = 0x8,
-       HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_LOW = 0x0,
-       HDMI_A_VIDPOLCFG_HSYNCPOL_MASK = 0x2,
-       HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_HIGH = 0x2,
-       HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_LOW = 0x0,
-};
-#endif /* __IMX_HDMI_H__ */
diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c
deleted file mode 100644 (file)
index 4662e00..0000000
+++ /dev/null
@@ -1,616 +0,0 @@
-/*
- * i.MX drm driver - LVDS display bridge
- *
- * Copyright (C) 2012 Sascha Hauer, Pengutronix
- *
- * 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.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/component.h>
-#include <drm/drmP.h>
-#include <drm/drm_fb_helper.h>
-#include <drm/drm_crtc_helper.h>
-#include <linux/mfd/syscon.h>
-#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
-#include <video/of_videomode.h>
-#include <linux/regmap.h>
-#include <linux/videodev2.h>
-
-#include "imx-drm.h"
-
-#define DRIVER_NAME "imx-ldb"
-
-#define LDB_CH0_MODE_EN_TO_DI0         (1 << 0)
-#define LDB_CH0_MODE_EN_TO_DI1         (3 << 0)
-#define LDB_CH0_MODE_EN_MASK           (3 << 0)
-#define LDB_CH1_MODE_EN_TO_DI0         (1 << 2)
-#define LDB_CH1_MODE_EN_TO_DI1         (3 << 2)
-#define LDB_CH1_MODE_EN_MASK           (3 << 2)
-#define LDB_SPLIT_MODE_EN              (1 << 4)
-#define LDB_DATA_WIDTH_CH0_24          (1 << 5)
-#define LDB_BIT_MAP_CH0_JEIDA          (1 << 6)
-#define LDB_DATA_WIDTH_CH1_24          (1 << 7)
-#define LDB_BIT_MAP_CH1_JEIDA          (1 << 8)
-#define LDB_DI0_VS_POL_ACT_LOW         (1 << 9)
-#define LDB_DI1_VS_POL_ACT_LOW         (1 << 10)
-#define LDB_BGREF_RMODE_INT            (1 << 15)
-
-#define con_to_imx_ldb_ch(x) container_of(x, struct imx_ldb_channel, connector)
-#define enc_to_imx_ldb_ch(x) container_of(x, struct imx_ldb_channel, encoder)
-
-struct imx_ldb;
-
-struct imx_ldb_channel {
-       struct imx_ldb *ldb;
-       struct drm_connector connector;
-       struct drm_encoder encoder;
-       struct device_node *child;
-       int chno;
-       void *edid;
-       int edid_len;
-       struct drm_display_mode mode;
-       int mode_valid;
-};
-
-struct bus_mux {
-       int reg;
-       int shift;
-       int mask;
-};
-
-struct imx_ldb {
-       struct regmap *regmap;
-       struct device *dev;
-       struct imx_ldb_channel channel[2];
-       struct clk *clk[2]; /* our own clock */
-       struct clk *clk_sel[4]; /* parent of display clock */
-       struct clk *clk_pll[2]; /* upstream clock we can adjust */
-       u32 ldb_ctrl;
-       const struct bus_mux *lvds_mux;
-};
-
-static enum drm_connector_status imx_ldb_connector_detect(
-               struct drm_connector *connector, bool force)
-{
-       return connector_status_connected;
-}
-
-static int imx_ldb_connector_get_modes(struct drm_connector *connector)
-{
-       struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector);
-       int num_modes = 0;
-
-       if (imx_ldb_ch->edid) {
-               drm_mode_connector_update_edid_property(connector,
-                                                       imx_ldb_ch->edid);
-               num_modes = drm_add_edid_modes(connector, imx_ldb_ch->edid);
-       }
-
-       if (imx_ldb_ch->mode_valid) {
-               struct drm_display_mode *mode;
-
-               mode = drm_mode_create(connector->dev);
-               if (!mode)
-                       return -EINVAL;
-               drm_mode_copy(mode, &imx_ldb_ch->mode);
-               mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
-               drm_mode_probed_add(connector, mode);
-               num_modes++;
-       }
-
-       return num_modes;
-}
-
-static struct drm_encoder *imx_ldb_connector_best_encoder(
-               struct drm_connector *connector)
-{
-       struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector);
-
-       return &imx_ldb_ch->encoder;
-}
-
-static void imx_ldb_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-}
-
-static bool imx_ldb_encoder_mode_fixup(struct drm_encoder *encoder,
-                          const struct drm_display_mode *mode,
-                          struct drm_display_mode *adjusted_mode)
-{
-       return true;
-}
-
-static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno,
-               unsigned long serial_clk, unsigned long di_clk)
-{
-       int ret;
-
-       dev_dbg(ldb->dev, "%s: now: %ld want: %ld\n", __func__,
-                       clk_get_rate(ldb->clk_pll[chno]), serial_clk);
-       clk_set_rate(ldb->clk_pll[chno], serial_clk);
-
-       dev_dbg(ldb->dev, "%s after: %ld\n", __func__,
-                       clk_get_rate(ldb->clk_pll[chno]));
-
-       dev_dbg(ldb->dev, "%s: now: %ld want: %ld\n", __func__,
-                       clk_get_rate(ldb->clk[chno]),
-                       (long int)di_clk);
-       clk_set_rate(ldb->clk[chno], di_clk);
-
-       dev_dbg(ldb->dev, "%s after: %ld\n", __func__,
-                       clk_get_rate(ldb->clk[chno]));
-
-       /* set display clock mux to LDB input clock */
-       ret = clk_set_parent(ldb->clk_sel[mux], ldb->clk[chno]);
-       if (ret)
-               dev_err(ldb->dev,
-                       "unable to set di%d parent clock to ldb_di%d\n", mux,
-                       chno);
-}
-
-static void imx_ldb_encoder_prepare(struct drm_encoder *encoder)
-{
-       struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
-       struct imx_ldb *ldb = imx_ldb_ch->ldb;
-       struct drm_display_mode *mode = &encoder->crtc->mode;
-       u32 pixel_fmt;
-       unsigned long serial_clk;
-       unsigned long di_clk = mode->clock * 1000;
-       int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder);
-
-       if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) {
-               /* dual channel LVDS mode */
-               serial_clk = 3500UL * mode->clock;
-               imx_ldb_set_clock(ldb, mux, 0, serial_clk, di_clk);
-               imx_ldb_set_clock(ldb, mux, 1, serial_clk, di_clk);
-       } else {
-               serial_clk = 7000UL * mode->clock;
-               imx_ldb_set_clock(ldb, mux, imx_ldb_ch->chno, serial_clk,
-                               di_clk);
-       }
-
-       switch (imx_ldb_ch->chno) {
-       case 0:
-               pixel_fmt = (ldb->ldb_ctrl & LDB_DATA_WIDTH_CH0_24) ?
-                       V4L2_PIX_FMT_RGB24 : V4L2_PIX_FMT_BGR666;
-               break;
-       case 1:
-               pixel_fmt = (ldb->ldb_ctrl & LDB_DATA_WIDTH_CH1_24) ?
-                       V4L2_PIX_FMT_RGB24 : V4L2_PIX_FMT_BGR666;
-               break;
-       default:
-               dev_err(ldb->dev, "unable to config di%d panel format\n",
-                       imx_ldb_ch->chno);
-               pixel_fmt = V4L2_PIX_FMT_RGB24;
-       }
-
-       imx_drm_panel_format(encoder, pixel_fmt);
-}
-
-static void imx_ldb_encoder_commit(struct drm_encoder *encoder)
-{
-       struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
-       struct imx_ldb *ldb = imx_ldb_ch->ldb;
-       int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
-       int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder);
-
-       if (dual) {
-               clk_prepare_enable(ldb->clk[0]);
-               clk_prepare_enable(ldb->clk[1]);
-       }
-
-       if (imx_ldb_ch == &ldb->channel[0] || dual) {
-               ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK;
-               if (mux == 0 || ldb->lvds_mux)
-                       ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI0;
-               else if (mux == 1)
-                       ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI1;
-       }
-       if (imx_ldb_ch == &ldb->channel[1] || dual) {
-               ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK;
-               if (mux == 1 || ldb->lvds_mux)
-                       ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI1;
-               else if (mux == 0)
-                       ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI0;
-       }
-
-       if (ldb->lvds_mux) {
-               const struct bus_mux *lvds_mux = NULL;
-
-               if (imx_ldb_ch == &ldb->channel[0])
-                       lvds_mux = &ldb->lvds_mux[0];
-               else if (imx_ldb_ch == &ldb->channel[1])
-                       lvds_mux = &ldb->lvds_mux[1];
-
-               regmap_update_bits(ldb->regmap, lvds_mux->reg, lvds_mux->mask,
-                                  mux << lvds_mux->shift);
-       }
-
-       regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl);
-}
-
-static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder,
-                        struct drm_display_mode *mode,
-                        struct drm_display_mode *adjusted_mode)
-{
-       struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
-       struct imx_ldb *ldb = imx_ldb_ch->ldb;
-       int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
-
-       if (mode->clock > 170000) {
-               dev_warn(ldb->dev,
-                        "%s: mode exceeds 170 MHz pixel clock\n", __func__);
-       }
-       if (mode->clock > 85000 && !dual) {
-               dev_warn(ldb->dev,
-                        "%s: mode exceeds 85 MHz pixel clock\n", __func__);
-       }
-
-       /* FIXME - assumes straight connections DI0 --> CH0, DI1 --> CH1 */
-       if (imx_ldb_ch == &ldb->channel[0]) {
-               if (mode->flags & DRM_MODE_FLAG_NVSYNC)
-                       ldb->ldb_ctrl |= LDB_DI0_VS_POL_ACT_LOW;
-               else if (mode->flags & DRM_MODE_FLAG_PVSYNC)
-                       ldb->ldb_ctrl &= ~LDB_DI0_VS_POL_ACT_LOW;
-       }
-       if (imx_ldb_ch == &ldb->channel[1]) {
-               if (mode->flags & DRM_MODE_FLAG_NVSYNC)
-                       ldb->ldb_ctrl |= LDB_DI1_VS_POL_ACT_LOW;
-               else if (mode->flags & DRM_MODE_FLAG_PVSYNC)
-                       ldb->ldb_ctrl &= ~LDB_DI1_VS_POL_ACT_LOW;
-       }
-}
-
-static void imx_ldb_encoder_disable(struct drm_encoder *encoder)
-{
-       struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
-       struct imx_ldb *ldb = imx_ldb_ch->ldb;
-
-       /*
-        * imx_ldb_encoder_disable is called by
-        * drm_helper_disable_unused_functions without
-        * the encoder being enabled before.
-        */
-       if (imx_ldb_ch == &ldb->channel[0] &&
-           (ldb->ldb_ctrl & LDB_CH0_MODE_EN_MASK) == 0)
-               return;
-       else if (imx_ldb_ch == &ldb->channel[1] &&
-                (ldb->ldb_ctrl & LDB_CH1_MODE_EN_MASK) == 0)
-               return;
-
-       if (imx_ldb_ch == &ldb->channel[0])
-               ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK;
-       else if (imx_ldb_ch == &ldb->channel[1])
-               ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK;
-
-       regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl);
-
-       if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) {
-               clk_disable_unprepare(ldb->clk[0]);
-               clk_disable_unprepare(ldb->clk[1]);
-       }
-}
-
-static struct drm_connector_funcs imx_ldb_connector_funcs = {
-       .dpms = drm_helper_connector_dpms,
-       .fill_modes = drm_helper_probe_single_connector_modes,
-       .detect = imx_ldb_connector_detect,
-       .destroy = imx_drm_connector_destroy,
-};
-
-static struct drm_connector_helper_funcs imx_ldb_connector_helper_funcs = {
-       .get_modes = imx_ldb_connector_get_modes,
-       .best_encoder = imx_ldb_connector_best_encoder,
-};
-
-static struct drm_encoder_funcs imx_ldb_encoder_funcs = {
-       .destroy = imx_drm_encoder_destroy,
-};
-
-static struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = {
-       .dpms = imx_ldb_encoder_dpms,
-       .mode_fixup = imx_ldb_encoder_mode_fixup,
-       .prepare = imx_ldb_encoder_prepare,
-       .commit = imx_ldb_encoder_commit,
-       .mode_set = imx_ldb_encoder_mode_set,
-       .disable = imx_ldb_encoder_disable,
-};
-
-static int imx_ldb_get_clk(struct imx_ldb *ldb, int chno)
-{
-       char clkname[16];
-
-       snprintf(clkname, sizeof(clkname), "di%d", chno);
-       ldb->clk[chno] = devm_clk_get(ldb->dev, clkname);
-       if (IS_ERR(ldb->clk[chno]))
-               return PTR_ERR(ldb->clk[chno]);
-
-       snprintf(clkname, sizeof(clkname), "di%d_pll", chno);
-       ldb->clk_pll[chno] = devm_clk_get(ldb->dev, clkname);
-
-       return PTR_ERR_OR_ZERO(ldb->clk_pll[chno]);
-}
-
-static int imx_ldb_register(struct drm_device *drm,
-       struct imx_ldb_channel *imx_ldb_ch)
-{
-       struct imx_ldb *ldb = imx_ldb_ch->ldb;
-       int ret;
-
-       ret = imx_drm_encoder_parse_of(drm, &imx_ldb_ch->encoder,
-                                      imx_ldb_ch->child);
-       if (ret)
-               return ret;
-
-       ret = imx_ldb_get_clk(ldb, imx_ldb_ch->chno);
-       if (ret)
-               return ret;
-
-       if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) {
-               ret = imx_ldb_get_clk(ldb, 1);
-               if (ret)
-                       return ret;
-       }
-
-       drm_encoder_helper_add(&imx_ldb_ch->encoder,
-                       &imx_ldb_encoder_helper_funcs);
-       drm_encoder_init(drm, &imx_ldb_ch->encoder, &imx_ldb_encoder_funcs,
-                        DRM_MODE_ENCODER_LVDS);
-
-       drm_connector_helper_add(&imx_ldb_ch->connector,
-                       &imx_ldb_connector_helper_funcs);
-       drm_connector_init(drm, &imx_ldb_ch->connector,
-                          &imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
-
-       drm_mode_connector_attach_encoder(&imx_ldb_ch->connector,
-                       &imx_ldb_ch->encoder);
-
-       return 0;
-}
-
-enum {
-       LVDS_BIT_MAP_SPWG,
-       LVDS_BIT_MAP_JEIDA
-};
-
-static const char * const imx_ldb_bit_mappings[] = {
-       [LVDS_BIT_MAP_SPWG]  = "spwg",
-       [LVDS_BIT_MAP_JEIDA] = "jeida",
-};
-
-static const int of_get_data_mapping(struct device_node *np)
-{
-       const char *bm;
-       int ret, i;
-
-       ret = of_property_read_string(np, "fsl,data-mapping", &bm);
-       if (ret < 0)
-               return ret;
-
-       for (i = 0; i < ARRAY_SIZE(imx_ldb_bit_mappings); i++)
-               if (!strcasecmp(bm, imx_ldb_bit_mappings[i]))
-                       return i;
-
-       return -EINVAL;
-}
-
-static struct bus_mux imx6q_lvds_mux[2] = {
-       {
-               .reg = IOMUXC_GPR3,
-               .shift = 6,
-               .mask = IMX6Q_GPR3_LVDS0_MUX_CTL_MASK,
-       }, {
-               .reg = IOMUXC_GPR3,
-               .shift = 8,
-               .mask = IMX6Q_GPR3_LVDS1_MUX_CTL_MASK,
-       }
-};
-
-/*
- * For a device declaring compatible = "fsl,imx6q-ldb", "fsl,imx53-ldb",
- * of_match_device will walk through this list and take the first entry
- * matching any of its compatible values. Therefore, the more generic
- * entries (in this case fsl,imx53-ldb) need to be ordered last.
- */
-static const struct of_device_id imx_ldb_dt_ids[] = {
-       { .compatible = "fsl,imx6q-ldb", .data = imx6q_lvds_mux, },
-       { .compatible = "fsl,imx53-ldb", .data = NULL, },
-       { }
-};
-MODULE_DEVICE_TABLE(of, imx_ldb_dt_ids);
-
-static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
-{
-       struct drm_device *drm = data;
-       struct device_node *np = dev->of_node;
-       const struct of_device_id *of_id =
-                       of_match_device(imx_ldb_dt_ids, dev);
-       struct device_node *child;
-       const u8 *edidp;
-       struct imx_ldb *imx_ldb;
-       int datawidth;
-       int mapping;
-       int dual;
-       int ret;
-       int i;
-
-       imx_ldb = devm_kzalloc(dev, sizeof(*imx_ldb), GFP_KERNEL);
-       if (!imx_ldb)
-               return -ENOMEM;
-
-       imx_ldb->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
-       if (IS_ERR(imx_ldb->regmap)) {
-               dev_err(dev, "failed to get parent regmap\n");
-               return PTR_ERR(imx_ldb->regmap);
-       }
-
-       imx_ldb->dev = dev;
-
-       if (of_id)
-               imx_ldb->lvds_mux = of_id->data;
-
-       dual = of_property_read_bool(np, "fsl,dual-channel");
-       if (dual)
-               imx_ldb->ldb_ctrl |= LDB_SPLIT_MODE_EN;
-
-       /*
-        * There are three different possible clock mux configurations:
-        * i.MX53:  ipu1_di0_sel, ipu1_di1_sel
-        * i.MX6q:  ipu1_di0_sel, ipu1_di1_sel, ipu2_di0_sel, ipu2_di1_sel
-        * i.MX6dl: ipu1_di0_sel, ipu1_di1_sel, lcdif_sel
-        * Map them all to di0_sel...di3_sel.
-        */
-       for (i = 0; i < 4; i++) {
-               char clkname[16];
-
-               sprintf(clkname, "di%d_sel", i);
-               imx_ldb->clk_sel[i] = devm_clk_get(imx_ldb->dev, clkname);
-               if (IS_ERR(imx_ldb->clk_sel[i])) {
-                       ret = PTR_ERR(imx_ldb->clk_sel[i]);
-                       imx_ldb->clk_sel[i] = NULL;
-                       break;
-               }
-       }
-       if (i == 0)
-               return ret;
-
-       for_each_child_of_node(np, child) {
-               struct imx_ldb_channel *channel;
-
-               ret = of_property_read_u32(child, "reg", &i);
-               if (ret || i < 0 || i > 1)
-                       return -EINVAL;
-
-               if (dual && i > 0) {
-                       dev_warn(dev, "dual-channel mode, ignoring second output\n");
-                       continue;
-               }
-
-               if (!of_device_is_available(child))
-                       continue;
-
-               channel = &imx_ldb->channel[i];
-               channel->ldb = imx_ldb;
-               channel->chno = i;
-               channel->child = child;
-
-               edidp = of_get_property(child, "edid", &channel->edid_len);
-               if (edidp) {
-                       channel->edid = kmemdup(edidp, channel->edid_len,
-                                               GFP_KERNEL);
-               } else {
-                       ret = of_get_drm_display_mode(child, &channel->mode, 0);
-                       if (!ret)
-                               channel->mode_valid = 1;
-               }
-
-               ret = of_property_read_u32(child, "fsl,data-width", &datawidth);
-               if (ret)
-                       datawidth = 0;
-               else if (datawidth != 18 && datawidth != 24)
-                       return -EINVAL;
-
-               mapping = of_get_data_mapping(child);
-               switch (mapping) {
-               case LVDS_BIT_MAP_SPWG:
-                       if (datawidth == 24) {
-                               if (i == 0 || dual)
-                                       imx_ldb->ldb_ctrl |=
-                                               LDB_DATA_WIDTH_CH0_24;
-                               if (i == 1 || dual)
-                                       imx_ldb->ldb_ctrl |=
-                                               LDB_DATA_WIDTH_CH1_24;
-                       }
-                       break;
-               case LVDS_BIT_MAP_JEIDA:
-                       if (datawidth == 18) {
-                               dev_err(dev, "JEIDA standard only supported in 24 bit\n");
-                               return -EINVAL;
-                       }
-                       if (i == 0 || dual)
-                               imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 |
-                                       LDB_BIT_MAP_CH0_JEIDA;
-                       if (i == 1 || dual)
-                               imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 |
-                                       LDB_BIT_MAP_CH1_JEIDA;
-                       break;
-               default:
-                       dev_err(dev, "data mapping not specified or invalid\n");
-                       return -EINVAL;
-               }
-
-               ret = imx_ldb_register(drm, channel);
-               if (ret)
-                       return ret;
-       }
-
-       dev_set_drvdata(dev, imx_ldb);
-
-       return 0;
-}
-
-static void imx_ldb_unbind(struct device *dev, struct device *master,
-       void *data)
-{
-       struct imx_ldb *imx_ldb = dev_get_drvdata(dev);
-       int i;
-
-       for (i = 0; i < 2; i++) {
-               struct imx_ldb_channel *channel = &imx_ldb->channel[i];
-
-               if (!channel->connector.funcs)
-                       continue;
-
-               channel->connector.funcs->destroy(&channel->connector);
-               channel->encoder.funcs->destroy(&channel->encoder);
-       }
-}
-
-static const struct component_ops imx_ldb_ops = {
-       .bind   = imx_ldb_bind,
-       .unbind = imx_ldb_unbind,
-};
-
-static int imx_ldb_probe(struct platform_device *pdev)
-{
-       return component_add(&pdev->dev, &imx_ldb_ops);
-}
-
-static int imx_ldb_remove(struct platform_device *pdev)
-{
-       component_del(&pdev->dev, &imx_ldb_ops);
-       return 0;
-}
-
-static struct platform_driver imx_ldb_driver = {
-       .probe          = imx_ldb_probe,
-       .remove         = imx_ldb_remove,
-       .driver         = {
-               .of_match_table = imx_ldb_dt_ids,
-               .name   = DRIVER_NAME,
-               .owner  = THIS_MODULE,
-       },
-};
-
-module_platform_driver(imx_ldb_driver);
-
-MODULE_DESCRIPTION("i.MX LVDS driver");
-MODULE_AUTHOR("Sascha Hauer, Pengutronix");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/staging/imx-drm/imx-tve.c b/drivers/staging/imx-drm/imx-tve.c
deleted file mode 100644 (file)
index 42c651b..0000000
+++ /dev/null
@@ -1,736 +0,0 @@
-/*
- * i.MX drm driver - Television Encoder (TVEv2)
- *
- * Copyright (C) 2013 Philipp Zabel, Pengutronix
- *
- * 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.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/clk.h>
-#include <linux/clk-provider.h>
-#include <linux/component.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/regmap.h>
-#include <linux/regulator/consumer.h>
-#include <linux/spinlock.h>
-#include <linux/videodev2.h>
-#include <drm/drmP.h>
-#include <drm/drm_fb_helper.h>
-#include <drm/drm_crtc_helper.h>
-#include <video/imx-ipu-v3.h>
-
-#include "imx-drm.h"
-
-#define TVE_COM_CONF_REG       0x00
-#define TVE_TVDAC0_CONT_REG    0x28
-#define TVE_TVDAC1_CONT_REG    0x2c
-#define TVE_TVDAC2_CONT_REG    0x30
-#define TVE_CD_CONT_REG                0x34
-#define TVE_INT_CONT_REG       0x64
-#define TVE_STAT_REG           0x68
-#define TVE_TST_MODE_REG       0x6c
-#define TVE_MV_CONT_REG                0xdc
-
-/* TVE_COM_CONF_REG */
-#define TVE_SYNC_CH_2_EN       BIT(22)
-#define TVE_SYNC_CH_1_EN       BIT(21)
-#define TVE_SYNC_CH_0_EN       BIT(20)
-#define TVE_TV_OUT_MODE_MASK   (0x7 << 12)
-#define TVE_TV_OUT_DISABLE     (0x0 << 12)
-#define TVE_TV_OUT_CVBS_0      (0x1 << 12)
-#define TVE_TV_OUT_CVBS_2      (0x2 << 12)
-#define TVE_TV_OUT_CVBS_0_2    (0x3 << 12)
-#define TVE_TV_OUT_SVIDEO_0_1  (0x4 << 12)
-#define TVE_TV_OUT_SVIDEO_0_1_CVBS2_2  (0x5 << 12)
-#define TVE_TV_OUT_YPBPR       (0x6 << 12)
-#define TVE_TV_OUT_RGB         (0x7 << 12)
-#define TVE_TV_STAND_MASK      (0xf << 8)
-#define TVE_TV_STAND_HD_1080P30        (0xc << 8)
-#define TVE_P2I_CONV_EN                BIT(7)
-#define TVE_INP_VIDEO_FORM     BIT(6)
-#define TVE_INP_YCBCR_422      (0x0 << 6)
-#define TVE_INP_YCBCR_444      (0x1 << 6)
-#define TVE_DATA_SOURCE_MASK   (0x3 << 4)
-#define TVE_DATA_SOURCE_BUS1   (0x0 << 4)
-#define TVE_DATA_SOURCE_BUS2   (0x1 << 4)
-#define TVE_DATA_SOURCE_EXT    (0x2 << 4)
-#define TVE_DATA_SOURCE_TESTGEN        (0x3 << 4)
-#define TVE_IPU_CLK_EN_OFS     3
-#define TVE_IPU_CLK_EN         BIT(3)
-#define TVE_DAC_SAMP_RATE_OFS  1
-#define TVE_DAC_SAMP_RATE_WIDTH        2
-#define TVE_DAC_SAMP_RATE_MASK (0x3 << 1)
-#define TVE_DAC_FULL_RATE      (0x0 << 1)
-#define TVE_DAC_DIV2_RATE      (0x1 << 1)
-#define TVE_DAC_DIV4_RATE      (0x2 << 1)
-#define TVE_EN                 BIT(0)
-
-/* TVE_TVDACx_CONT_REG */
-#define TVE_TVDAC_GAIN_MASK    (0x3f << 0)
-
-/* TVE_CD_CONT_REG */
-#define TVE_CD_CH_2_SM_EN      BIT(22)
-#define TVE_CD_CH_1_SM_EN      BIT(21)
-#define TVE_CD_CH_0_SM_EN      BIT(20)
-#define TVE_CD_CH_2_LM_EN      BIT(18)
-#define TVE_CD_CH_1_LM_EN      BIT(17)
-#define TVE_CD_CH_0_LM_EN      BIT(16)
-#define TVE_CD_CH_2_REF_LVL    BIT(10)
-#define TVE_CD_CH_1_REF_LVL    BIT(9)
-#define TVE_CD_CH_0_REF_LVL    BIT(8)
-#define TVE_CD_EN              BIT(0)
-
-/* TVE_INT_CONT_REG */
-#define TVE_FRAME_END_IEN      BIT(13)
-#define TVE_CD_MON_END_IEN     BIT(2)
-#define TVE_CD_SM_IEN          BIT(1)
-#define TVE_CD_LM_IEN          BIT(0)
-
-/* TVE_TST_MODE_REG */
-#define TVE_TVDAC_TEST_MODE_MASK       (0x7 << 0)
-
-#define con_to_tve(x) container_of(x, struct imx_tve, connector)
-#define enc_to_tve(x) container_of(x, struct imx_tve, encoder)
-
-enum {
-       TVE_MODE_TVOUT,
-       TVE_MODE_VGA,
-};
-
-struct imx_tve {
-       struct drm_connector connector;
-       struct drm_encoder encoder;
-       struct device *dev;
-       spinlock_t lock;        /* register lock */
-       bool enabled;
-       int mode;
-
-       struct regmap *regmap;
-       struct regulator *dac_reg;
-       struct i2c_adapter *ddc;
-       struct clk *clk;
-       struct clk *di_sel_clk;
-       struct clk_hw clk_hw_di;
-       struct clk *di_clk;
-       int vsync_pin;
-       int hsync_pin;
-};
-
-static void tve_lock(void *__tve)
-__acquires(&tve->lock)
-{
-       struct imx_tve *tve = __tve;
-
-       spin_lock(&tve->lock);
-}
-
-static void tve_unlock(void *__tve)
-__releases(&tve->lock)
-{
-       struct imx_tve *tve = __tve;
-
-       spin_unlock(&tve->lock);
-}
-
-static void tve_enable(struct imx_tve *tve)
-{
-       int ret;
-
-       if (!tve->enabled) {
-               tve->enabled = true;
-               clk_prepare_enable(tve->clk);
-               ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG,
-                                        TVE_IPU_CLK_EN | TVE_EN,
-                                        TVE_IPU_CLK_EN | TVE_EN);
-       }
-
-       /* clear interrupt status register */
-       regmap_write(tve->regmap, TVE_STAT_REG, 0xffffffff);
-
-       /* cable detection irq disabled in VGA mode, enabled in TVOUT mode */
-       if (tve->mode == TVE_MODE_VGA)
-               regmap_write(tve->regmap, TVE_INT_CONT_REG, 0);
-       else
-               regmap_write(tve->regmap, TVE_INT_CONT_REG,
-                            TVE_CD_SM_IEN |
-                            TVE_CD_LM_IEN |
-                            TVE_CD_MON_END_IEN);
-}
-
-static void tve_disable(struct imx_tve *tve)
-{
-       int ret;
-
-       if (tve->enabled) {
-               tve->enabled = false;
-               ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG,
-                                        TVE_IPU_CLK_EN | TVE_EN, 0);
-               clk_disable_unprepare(tve->clk);
-       }
-}
-
-static int tve_setup_tvout(struct imx_tve *tve)
-{
-       return -ENOTSUPP;
-}
-
-static int tve_setup_vga(struct imx_tve *tve)
-{
-       unsigned int mask;
-       unsigned int val;
-       int ret;
-
-       /* set gain to (1 + 10/128) to provide 0.7V peak-to-peak amplitude */
-       ret = regmap_update_bits(tve->regmap, TVE_TVDAC0_CONT_REG,
-                                TVE_TVDAC_GAIN_MASK, 0x0a);
-       ret = regmap_update_bits(tve->regmap, TVE_TVDAC1_CONT_REG,
-                                TVE_TVDAC_GAIN_MASK, 0x0a);
-       ret = regmap_update_bits(tve->regmap, TVE_TVDAC2_CONT_REG,
-                                TVE_TVDAC_GAIN_MASK, 0x0a);
-
-       /* set configuration register */
-       mask = TVE_DATA_SOURCE_MASK | TVE_INP_VIDEO_FORM;
-       val  = TVE_DATA_SOURCE_BUS2 | TVE_INP_YCBCR_444;
-       mask |= TVE_TV_STAND_MASK       | TVE_P2I_CONV_EN;
-       val  |= TVE_TV_STAND_HD_1080P30 | 0;
-       mask |= TVE_TV_OUT_MODE_MASK | TVE_SYNC_CH_0_EN;
-       val  |= TVE_TV_OUT_RGB       | TVE_SYNC_CH_0_EN;
-       ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, mask, val);
-       if (ret < 0) {
-               dev_err(tve->dev, "failed to set configuration: %d\n", ret);
-               return ret;
-       }
-
-       /* set test mode (as documented) */
-       ret = regmap_update_bits(tve->regmap, TVE_TST_MODE_REG,
-                                TVE_TVDAC_TEST_MODE_MASK, 1);
-
-       return 0;
-}
-
-static enum drm_connector_status imx_tve_connector_detect(
-                               struct drm_connector *connector, bool force)
-{
-       return connector_status_connected;
-}
-
-static int imx_tve_connector_get_modes(struct drm_connector *connector)
-{
-       struct imx_tve *tve = con_to_tve(connector);
-       struct edid *edid;
-       int ret = 0;
-
-       if (!tve->ddc)
-               return 0;
-
-       edid = drm_get_edid(connector, tve->ddc);
-       if (edid) {
-               drm_mode_connector_update_edid_property(connector, edid);
-               ret = drm_add_edid_modes(connector, edid);
-               kfree(edid);
-       }
-
-       return ret;
-}
-
-static int imx_tve_connector_mode_valid(struct drm_connector *connector,
-                                       struct drm_display_mode *mode)
-{
-       struct imx_tve *tve = con_to_tve(connector);
-       unsigned long rate;
-
-       /* pixel clock with 2x oversampling */
-       rate = clk_round_rate(tve->clk, 2000UL * mode->clock) / 2000;
-       if (rate == mode->clock)
-               return MODE_OK;
-
-       /* pixel clock without oversampling */
-       rate = clk_round_rate(tve->clk, 1000UL * mode->clock) / 1000;
-       if (rate == mode->clock)
-               return MODE_OK;
-
-       dev_warn(tve->dev, "ignoring mode %dx%d\n",
-                mode->hdisplay, mode->vdisplay);
-
-       return MODE_BAD;
-}
-
-static struct drm_encoder *imx_tve_connector_best_encoder(
-               struct drm_connector *connector)
-{
-       struct imx_tve *tve = con_to_tve(connector);
-
-       return &tve->encoder;
-}
-
-static void imx_tve_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-       struct imx_tve *tve = enc_to_tve(encoder);
-       int ret;
-
-       ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG,
-                                TVE_TV_OUT_MODE_MASK, TVE_TV_OUT_DISABLE);
-       if (ret < 0)
-               dev_err(tve->dev, "failed to disable TVOUT: %d\n", ret);
-}
-
-static bool imx_tve_encoder_mode_fixup(struct drm_encoder *encoder,
-                                      const struct drm_display_mode *mode,
-                                      struct drm_display_mode *adjusted_mode)
-{
-       return true;
-}
-
-static void imx_tve_encoder_prepare(struct drm_encoder *encoder)
-{
-       struct imx_tve *tve = enc_to_tve(encoder);
-
-       tve_disable(tve);
-
-       switch (tve->mode) {
-       case TVE_MODE_VGA:
-               imx_drm_panel_format_pins(encoder, IPU_PIX_FMT_GBR24,
-                               tve->hsync_pin, tve->vsync_pin);
-               break;
-       case TVE_MODE_TVOUT:
-               imx_drm_panel_format(encoder, V4L2_PIX_FMT_YUV444);
-               break;
-       }
-}
-
-static void imx_tve_encoder_mode_set(struct drm_encoder *encoder,
-                                    struct drm_display_mode *mode,
-                                    struct drm_display_mode *adjusted_mode)
-{
-       struct imx_tve *tve = enc_to_tve(encoder);
-       unsigned long rounded_rate;
-       unsigned long rate;
-       int div = 1;
-       int ret;
-
-       /*
-        * FIXME
-        * we should try 4k * mode->clock first,
-        * and enable 4x oversampling for lower resolutions
-        */
-       rate = 2000UL * mode->clock;
-       clk_set_rate(tve->clk, rate);
-       rounded_rate = clk_get_rate(tve->clk);
-       if (rounded_rate >= rate)
-               div = 2;
-       clk_set_rate(tve->di_clk, rounded_rate / div);
-
-       ret = clk_set_parent(tve->di_sel_clk, tve->di_clk);
-       if (ret < 0) {
-               dev_err(tve->dev, "failed to set di_sel parent to tve_di: %d\n",
-                       ret);
-       }
-
-       if (tve->mode == TVE_MODE_VGA)
-               tve_setup_vga(tve);
-       else
-               tve_setup_tvout(tve);
-}
-
-static void imx_tve_encoder_commit(struct drm_encoder *encoder)
-{
-       struct imx_tve *tve = enc_to_tve(encoder);
-
-       tve_enable(tve);
-}
-
-static void imx_tve_encoder_disable(struct drm_encoder *encoder)
-{
-       struct imx_tve *tve = enc_to_tve(encoder);
-
-       tve_disable(tve);
-}
-
-static struct drm_connector_funcs imx_tve_connector_funcs = {
-       .dpms = drm_helper_connector_dpms,
-       .fill_modes = drm_helper_probe_single_connector_modes,
-       .detect = imx_tve_connector_detect,
-       .destroy = imx_drm_connector_destroy,
-};
-
-static struct drm_connector_helper_funcs imx_tve_connector_helper_funcs = {
-       .get_modes = imx_tve_connector_get_modes,
-       .best_encoder = imx_tve_connector_best_encoder,
-       .mode_valid = imx_tve_connector_mode_valid,
-};
-
-static struct drm_encoder_funcs imx_tve_encoder_funcs = {
-       .destroy = imx_drm_encoder_destroy,
-};
-
-static struct drm_encoder_helper_funcs imx_tve_encoder_helper_funcs = {
-       .dpms = imx_tve_encoder_dpms,
-       .mode_fixup = imx_tve_encoder_mode_fixup,
-       .prepare = imx_tve_encoder_prepare,
-       .mode_set = imx_tve_encoder_mode_set,
-       .commit = imx_tve_encoder_commit,
-       .disable = imx_tve_encoder_disable,
-};
-
-static irqreturn_t imx_tve_irq_handler(int irq, void *data)
-{
-       struct imx_tve *tve = data;
-       unsigned int val;
-
-       regmap_read(tve->regmap, TVE_STAT_REG, &val);
-
-       /* clear interrupt status register */
-       regmap_write(tve->regmap, TVE_STAT_REG, 0xffffffff);
-
-       return IRQ_HANDLED;
-}
-
-static unsigned long clk_tve_di_recalc_rate(struct clk_hw *hw,
-                                           unsigned long parent_rate)
-{
-       struct imx_tve *tve = container_of(hw, struct imx_tve, clk_hw_di);
-       unsigned int val;
-       int ret;
-
-       ret = regmap_read(tve->regmap, TVE_COM_CONF_REG, &val);
-       if (ret < 0)
-               return 0;
-
-       switch (val & TVE_DAC_SAMP_RATE_MASK) {
-       case TVE_DAC_DIV4_RATE:
-               return parent_rate / 4;
-       case TVE_DAC_DIV2_RATE:
-               return parent_rate / 2;
-       case TVE_DAC_FULL_RATE:
-       default:
-               return parent_rate;
-       }
-
-       return 0;
-}
-
-static long clk_tve_di_round_rate(struct clk_hw *hw, unsigned long rate,
-                                 unsigned long *prate)
-{
-       unsigned long div;
-
-       div = *prate / rate;
-       if (div >= 4)
-               return *prate / 4;
-       else if (div >= 2)
-               return *prate / 2;
-       return *prate;
-}
-
-static int clk_tve_di_set_rate(struct clk_hw *hw, unsigned long rate,
-                              unsigned long parent_rate)
-{
-       struct imx_tve *tve = container_of(hw, struct imx_tve, clk_hw_di);
-       unsigned long div;
-       u32 val;
-       int ret;
-
-       div = parent_rate / rate;
-       if (div >= 4)
-               val = TVE_DAC_DIV4_RATE;
-       else if (div >= 2)
-               val = TVE_DAC_DIV2_RATE;
-       else
-               val = TVE_DAC_FULL_RATE;
-
-       ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG,
-                                TVE_DAC_SAMP_RATE_MASK, val);
-
-       if (ret < 0) {
-               dev_err(tve->dev, "failed to set divider: %d\n", ret);
-               return ret;
-       }
-
-       return 0;
-}
-
-static struct clk_ops clk_tve_di_ops = {
-       .round_rate = clk_tve_di_round_rate,
-       .set_rate = clk_tve_di_set_rate,
-       .recalc_rate = clk_tve_di_recalc_rate,
-};
-
-static int tve_clk_init(struct imx_tve *tve, void __iomem *base)
-{
-       const char *tve_di_parent[1];
-       struct clk_init_data init = {
-               .name = "tve_di",
-               .ops = &clk_tve_di_ops,
-               .num_parents = 1,
-               .flags = 0,
-       };
-
-       tve_di_parent[0] = __clk_get_name(tve->clk);
-       init.parent_names = (const char **)&tve_di_parent;
-
-       tve->clk_hw_di.init = &init;
-       tve->di_clk = clk_register(tve->dev, &tve->clk_hw_di);
-       if (IS_ERR(tve->di_clk)) {
-               dev_err(tve->dev, "failed to register TVE output clock: %ld\n",
-                       PTR_ERR(tve->di_clk));
-               return PTR_ERR(tve->di_clk);
-       }
-
-       return 0;
-}
-
-static int imx_tve_register(struct drm_device *drm, struct imx_tve *tve)
-{
-       int encoder_type;
-       int ret;
-
-       encoder_type = tve->mode == TVE_MODE_VGA ?
-                               DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC;
-
-       ret = imx_drm_encoder_parse_of(drm, &tve->encoder,
-                                      tve->dev->of_node);
-       if (ret)
-               return ret;
-
-       drm_encoder_helper_add(&tve->encoder, &imx_tve_encoder_helper_funcs);
-       drm_encoder_init(drm, &tve->encoder, &imx_tve_encoder_funcs,
-                        encoder_type);
-
-       drm_connector_helper_add(&tve->connector,
-                       &imx_tve_connector_helper_funcs);
-       drm_connector_init(drm, &tve->connector, &imx_tve_connector_funcs,
-                          DRM_MODE_CONNECTOR_VGA);
-
-       drm_mode_connector_attach_encoder(&tve->connector, &tve->encoder);
-
-       return 0;
-}
-
-static bool imx_tve_readable_reg(struct device *dev, unsigned int reg)
-{
-       return (reg % 4 == 0) && (reg <= 0xdc);
-}
-
-static struct regmap_config tve_regmap_config = {
-       .reg_bits = 32,
-       .val_bits = 32,
-       .reg_stride = 4,
-
-       .readable_reg = imx_tve_readable_reg,
-
-       .lock = tve_lock,
-       .unlock = tve_unlock,
-
-       .max_register = 0xdc,
-};
-
-static const char * const imx_tve_modes[] = {
-       [TVE_MODE_TVOUT]  = "tvout",
-       [TVE_MODE_VGA] = "vga",
-};
-
-static const int of_get_tve_mode(struct device_node *np)
-{
-       const char *bm;
-       int ret, i;
-
-       ret = of_property_read_string(np, "fsl,tve-mode", &bm);
-       if (ret < 0)
-               return ret;
-
-       for (i = 0; i < ARRAY_SIZE(imx_tve_modes); i++)
-               if (!strcasecmp(bm, imx_tve_modes[i]))
-                       return i;
-
-       return -EINVAL;
-}
-
-static int imx_tve_bind(struct device *dev, struct device *master, void *data)
-{
-       struct platform_device *pdev = to_platform_device(dev);
-       struct drm_device *drm = data;
-       struct device_node *np = dev->of_node;
-       struct device_node *ddc_node;
-       struct imx_tve *tve;
-       struct resource *res;
-       void __iomem *base;
-       unsigned int val;
-       int irq;
-       int ret;
-
-       tve = devm_kzalloc(dev, sizeof(*tve), GFP_KERNEL);
-       if (!tve)
-               return -ENOMEM;
-
-       tve->dev = dev;
-       spin_lock_init(&tve->lock);
-
-       ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
-       if (ddc_node) {
-               tve->ddc = of_find_i2c_adapter_by_node(ddc_node);
-               of_node_put(ddc_node);
-       }
-
-       tve->mode = of_get_tve_mode(np);
-       if (tve->mode != TVE_MODE_VGA) {
-               dev_err(dev, "only VGA mode supported, currently\n");
-               return -EINVAL;
-       }
-
-       if (tve->mode == TVE_MODE_VGA) {
-               ret = of_property_read_u32(np, "fsl,hsync-pin",
-                                          &tve->hsync_pin);
-
-               if (ret < 0) {
-                       dev_err(dev, "failed to get vsync pin\n");
-                       return ret;
-               }
-
-               ret |= of_property_read_u32(np, "fsl,vsync-pin",
-                                           &tve->vsync_pin);
-
-               if (ret < 0) {
-                       dev_err(dev, "failed to get vsync pin\n");
-                       return ret;
-               }
-       }
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       base = devm_ioremap_resource(dev, res);
-       if (IS_ERR(base))
-               return PTR_ERR(base);
-
-       tve_regmap_config.lock_arg = tve;
-       tve->regmap = devm_regmap_init_mmio_clk(dev, "tve", base,
-                                               &tve_regmap_config);
-       if (IS_ERR(tve->regmap)) {
-               dev_err(dev, "failed to init regmap: %ld\n",
-                       PTR_ERR(tve->regmap));
-               return PTR_ERR(tve->regmap);
-       }
-
-       irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(dev, "failed to get irq\n");
-               return irq;
-       }
-
-       ret = devm_request_threaded_irq(dev, irq, NULL,
-                                       imx_tve_irq_handler, IRQF_ONESHOT,
-                                       "imx-tve", tve);
-       if (ret < 0) {
-               dev_err(dev, "failed to request irq: %d\n", ret);
-               return ret;
-       }
-
-       tve->dac_reg = devm_regulator_get(dev, "dac");
-       if (!IS_ERR(tve->dac_reg)) {
-               regulator_set_voltage(tve->dac_reg, 2750000, 2750000);
-               ret = regulator_enable(tve->dac_reg);
-               if (ret)
-                       return ret;
-       }
-
-       tve->clk = devm_clk_get(dev, "tve");
-       if (IS_ERR(tve->clk)) {
-               dev_err(dev, "failed to get high speed tve clock: %ld\n",
-                       PTR_ERR(tve->clk));
-               return PTR_ERR(tve->clk);
-       }
-
-       /* this is the IPU DI clock input selector, can be parented to tve_di */
-       tve->di_sel_clk = devm_clk_get(dev, "di_sel");
-       if (IS_ERR(tve->di_sel_clk)) {
-               dev_err(dev, "failed to get ipu di mux clock: %ld\n",
-                       PTR_ERR(tve->di_sel_clk));
-               return PTR_ERR(tve->di_sel_clk);
-       }
-
-       ret = tve_clk_init(tve, base);
-       if (ret < 0)
-               return ret;
-
-       ret = regmap_read(tve->regmap, TVE_COM_CONF_REG, &val);
-       if (ret < 0) {
-               dev_err(dev, "failed to read configuration register: %d\n", ret);
-               return ret;
-       }
-       if (val != 0x00100000) {
-               dev_err(dev, "configuration register default value indicates this is not a TVEv2\n");
-               return -ENODEV;
-       }
-
-       /* disable cable detection for VGA mode */
-       ret = regmap_write(tve->regmap, TVE_CD_CONT_REG, 0);
-
-       ret = imx_tve_register(drm, tve);
-       if (ret)
-               return ret;
-
-       dev_set_drvdata(dev, tve);
-
-       return 0;
-}
-
-static void imx_tve_unbind(struct device *dev, struct device *master,
-       void *data)
-{
-       struct imx_tve *tve = dev_get_drvdata(dev);
-
-       tve->connector.funcs->destroy(&tve->connector);
-       tve->encoder.funcs->destroy(&tve->encoder);
-
-       if (!IS_ERR(tve->dac_reg))
-               regulator_disable(tve->dac_reg);
-}
-
-static const struct component_ops imx_tve_ops = {
-       .bind   = imx_tve_bind,
-       .unbind = imx_tve_unbind,
-};
-
-static int imx_tve_probe(struct platform_device *pdev)
-{
-       return component_add(&pdev->dev, &imx_tve_ops);
-}
-
-static int imx_tve_remove(struct platform_device *pdev)
-{
-       component_del(&pdev->dev, &imx_tve_ops);
-       return 0;
-}
-
-static const struct of_device_id imx_tve_dt_ids[] = {
-       { .compatible = "fsl,imx53-tve", },
-       { /* sentinel */ }
-};
-
-static struct platform_driver imx_tve_driver = {
-       .probe          = imx_tve_probe,
-       .remove         = imx_tve_remove,
-       .driver         = {
-               .of_match_table = imx_tve_dt_ids,
-               .name   = "imx-tve",
-               .owner  = THIS_MODULE,
-       },
-};
-
-module_platform_driver(imx_tve_driver);
-
-MODULE_DESCRIPTION("i.MX Television Encoder driver");
-MODULE_AUTHOR("Philipp Zabel, Pengutronix");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-tve");
diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/staging/imx-drm/ipuv3-crtc.c
deleted file mode 100644 (file)
index 11e84a2..0000000
+++ /dev/null
@@ -1,518 +0,0 @@
-/*
- * i.MX IPUv3 Graphics driver
- *
- * Copyright (C) 2011 Sascha Hauer, Pengutronix
- *
- * 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.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-#include <linux/component.h>
-#include <linux/module.h>
-#include <linux/export.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <drm/drmP.h>
-#include <drm/drm_crtc_helper.h>
-#include <linux/fb.h>
-#include <linux/clk.h>
-#include <linux/errno.h>
-#include <drm/drm_gem_cma_helper.h>
-#include <drm/drm_fb_cma_helper.h>
-
-#include <video/imx-ipu-v3.h>
-#include "imx-drm.h"
-#include "ipuv3-plane.h"
-
-#define DRIVER_DESC            "i.MX IPUv3 Graphics"
-
-struct ipu_crtc {
-       struct device           *dev;
-       struct drm_crtc         base;
-       struct imx_drm_crtc     *imx_crtc;
-
-       /* plane[0] is the full plane, plane[1] is the partial plane */
-       struct ipu_plane        *plane[2];
-
-       struct ipu_dc           *dc;
-       struct ipu_di           *di;
-       int                     enabled;
-       struct drm_pending_vblank_event *page_flip_event;
-       struct drm_framebuffer  *newfb;
-       int                     irq;
-       u32                     interface_pix_fmt;
-       unsigned long           di_clkflags;
-       int                     di_hsync_pin;
-       int                     di_vsync_pin;
-};
-
-#define to_ipu_crtc(x) container_of(x, struct ipu_crtc, base)
-
-static void ipu_fb_enable(struct ipu_crtc *ipu_crtc)
-{
-       struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
-
-       if (ipu_crtc->enabled)
-               return;
-
-       ipu_dc_enable(ipu);
-       ipu_plane_enable(ipu_crtc->plane[0]);
-       /* Start DC channel and DI after IDMAC */
-       ipu_dc_enable_channel(ipu_crtc->dc);
-       ipu_di_enable(ipu_crtc->di);
-
-       ipu_crtc->enabled = 1;
-}
-
-static void ipu_fb_disable(struct ipu_crtc *ipu_crtc)
-{
-       struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
-
-       if (!ipu_crtc->enabled)
-               return;
-
-       /* Stop DC channel and DI before IDMAC */
-       ipu_dc_disable_channel(ipu_crtc->dc);
-       ipu_di_disable(ipu_crtc->di);
-       ipu_plane_disable(ipu_crtc->plane[0]);
-       ipu_dc_disable(ipu);
-
-       ipu_crtc->enabled = 0;
-}
-
-static void ipu_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
-
-       dev_dbg(ipu_crtc->dev, "%s mode: %d\n", __func__, mode);
-
-       switch (mode) {
-       case DRM_MODE_DPMS_ON:
-               ipu_fb_enable(ipu_crtc);
-               break;
-       case DRM_MODE_DPMS_STANDBY:
-       case DRM_MODE_DPMS_SUSPEND:
-       case DRM_MODE_DPMS_OFF:
-               ipu_fb_disable(ipu_crtc);
-               break;
-       }
-}
-
-static int ipu_page_flip(struct drm_crtc *crtc,
-               struct drm_framebuffer *fb,
-               struct drm_pending_vblank_event *event,
-               uint32_t page_flip_flags)
-{
-       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
-       int ret;
-
-       if (ipu_crtc->newfb)
-               return -EBUSY;
-
-       ret = imx_drm_crtc_vblank_get(ipu_crtc->imx_crtc);
-       if (ret) {
-               dev_dbg(ipu_crtc->dev, "failed to acquire vblank counter\n");
-               list_del(&event->base.link);
-
-               return ret;
-       }
-
-       ipu_crtc->newfb = fb;
-       ipu_crtc->page_flip_event = event;
-       crtc->primary->fb = fb;
-
-       return 0;
-}
-
-static const struct drm_crtc_funcs ipu_crtc_funcs = {
-       .set_config = drm_crtc_helper_set_config,
-       .destroy = drm_crtc_cleanup,
-       .page_flip = ipu_page_flip,
-};
-
-static int ipu_crtc_mode_set(struct drm_crtc *crtc,
-                              struct drm_display_mode *orig_mode,
-                              struct drm_display_mode *mode,
-                              int x, int y,
-                              struct drm_framebuffer *old_fb)
-{
-       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
-       int ret;
-       struct ipu_di_signal_cfg sig_cfg = {};
-       u32 out_pixel_fmt;
-
-       dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__,
-                       mode->hdisplay);
-       dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__,
-                       mode->vdisplay);
-
-       out_pixel_fmt = ipu_crtc->interface_pix_fmt;
-
-       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
-               sig_cfg.interlaced = 1;
-       if (mode->flags & DRM_MODE_FLAG_PHSYNC)
-               sig_cfg.Hsync_pol = 1;
-       if (mode->flags & DRM_MODE_FLAG_PVSYNC)
-               sig_cfg.Vsync_pol = 1;
-
-       sig_cfg.enable_pol = 1;
-       sig_cfg.clk_pol = 0;
-       sig_cfg.width = mode->hdisplay;
-       sig_cfg.height = mode->vdisplay;
-       sig_cfg.pixel_fmt = out_pixel_fmt;
-       sig_cfg.h_start_width = mode->htotal - mode->hsync_end;
-       sig_cfg.h_sync_width = mode->hsync_end - mode->hsync_start;
-       sig_cfg.h_end_width = mode->hsync_start - mode->hdisplay;
-
-       sig_cfg.v_start_width = mode->vtotal - mode->vsync_end;
-       sig_cfg.v_sync_width = mode->vsync_end - mode->vsync_start;
-       sig_cfg.v_end_width = mode->vsync_start - mode->vdisplay;
-       sig_cfg.pixelclock = mode->clock * 1000;
-       sig_cfg.clkflags = ipu_crtc->di_clkflags;
-
-       sig_cfg.v_to_h_sync = 0;
-
-       sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin;
-       sig_cfg.vsync_pin = ipu_crtc->di_vsync_pin;
-
-       ret = ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di, sig_cfg.interlaced,
-                       out_pixel_fmt, mode->hdisplay);
-       if (ret) {
-               dev_err(ipu_crtc->dev,
-                               "initializing display controller failed with %d\n",
-                               ret);
-               return ret;
-       }
-
-       ret = ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg);
-       if (ret) {
-               dev_err(ipu_crtc->dev,
-                               "initializing panel failed with %d\n", ret);
-               return ret;
-       }
-
-       return ipu_plane_mode_set(ipu_crtc->plane[0], crtc, mode,
-                                 crtc->primary->fb,
-                                 0, 0, mode->hdisplay, mode->vdisplay,
-                                 x, y, mode->hdisplay, mode->vdisplay);
-}
-
-static void ipu_crtc_handle_pageflip(struct ipu_crtc *ipu_crtc)
-{
-       unsigned long flags;
-       struct drm_device *drm = ipu_crtc->base.dev;
-
-       spin_lock_irqsave(&drm->event_lock, flags);
-       if (ipu_crtc->page_flip_event)
-               drm_send_vblank_event(drm, -1, ipu_crtc->page_flip_event);
-       ipu_crtc->page_flip_event = NULL;
-       imx_drm_crtc_vblank_put(ipu_crtc->imx_crtc);
-       spin_unlock_irqrestore(&drm->event_lock, flags);
-}
-
-static irqreturn_t ipu_irq_handler(int irq, void *dev_id)
-{
-       struct ipu_crtc *ipu_crtc = dev_id;
-
-       imx_drm_handle_vblank(ipu_crtc->imx_crtc);
-
-       if (ipu_crtc->newfb) {
-               struct ipu_plane *plane = ipu_crtc->plane[0];
-
-               ipu_crtc->newfb = NULL;
-               ipu_plane_set_base(plane, ipu_crtc->base.primary->fb,
-                                  plane->x, plane->y);
-               ipu_crtc_handle_pageflip(ipu_crtc);
-       }
-
-       return IRQ_HANDLED;
-}
-
-static bool ipu_crtc_mode_fixup(struct drm_crtc *crtc,
-                                 const struct drm_display_mode *mode,
-                                 struct drm_display_mode *adjusted_mode)
-{
-       return true;
-}
-
-static void ipu_crtc_prepare(struct drm_crtc *crtc)
-{
-       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
-
-       ipu_fb_disable(ipu_crtc);
-}
-
-static void ipu_crtc_commit(struct drm_crtc *crtc)
-{
-       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
-
-       ipu_fb_enable(ipu_crtc);
-}
-
-static struct drm_crtc_helper_funcs ipu_helper_funcs = {
-       .dpms = ipu_crtc_dpms,
-       .mode_fixup = ipu_crtc_mode_fixup,
-       .mode_set = ipu_crtc_mode_set,
-       .prepare = ipu_crtc_prepare,
-       .commit = ipu_crtc_commit,
-};
-
-static int ipu_enable_vblank(struct drm_crtc *crtc)
-{
-       return 0;
-}
-
-static void ipu_disable_vblank(struct drm_crtc *crtc)
-{
-       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
-
-       ipu_crtc->page_flip_event = NULL;
-       ipu_crtc->newfb = NULL;
-}
-
-static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type,
-               u32 pixfmt, int hsync_pin, int vsync_pin)
-{
-       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
-
-       ipu_crtc->interface_pix_fmt = pixfmt;
-       ipu_crtc->di_hsync_pin = hsync_pin;
-       ipu_crtc->di_vsync_pin = vsync_pin;
-
-       switch (encoder_type) {
-       case DRM_MODE_ENCODER_DAC:
-       case DRM_MODE_ENCODER_TVDAC:
-       case DRM_MODE_ENCODER_LVDS:
-               ipu_crtc->di_clkflags = IPU_DI_CLKMODE_SYNC |
-                       IPU_DI_CLKMODE_EXT;
-               break;
-       case DRM_MODE_ENCODER_TMDS:
-       case DRM_MODE_ENCODER_NONE:
-               ipu_crtc->di_clkflags = 0;
-               break;
-       }
-
-       return 0;
-}
-
-static const struct imx_drm_crtc_helper_funcs ipu_crtc_helper_funcs = {
-       .enable_vblank = ipu_enable_vblank,
-       .disable_vblank = ipu_disable_vblank,
-       .set_interface_pix_fmt = ipu_set_interface_pix_fmt,
-       .crtc_funcs = &ipu_crtc_funcs,
-       .crtc_helper_funcs = &ipu_helper_funcs,
-};
-
-static void ipu_put_resources(struct ipu_crtc *ipu_crtc)
-{
-       if (!IS_ERR_OR_NULL(ipu_crtc->dc))
-               ipu_dc_put(ipu_crtc->dc);
-       if (!IS_ERR_OR_NULL(ipu_crtc->di))
-               ipu_di_put(ipu_crtc->di);
-}
-
-static int ipu_get_resources(struct ipu_crtc *ipu_crtc,
-               struct ipu_client_platformdata *pdata)
-{
-       struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
-       int ret;
-
-       ipu_crtc->dc = ipu_dc_get(ipu, pdata->dc);
-       if (IS_ERR(ipu_crtc->dc)) {
-               ret = PTR_ERR(ipu_crtc->dc);
-               goto err_out;
-       }
-
-       ipu_crtc->di = ipu_di_get(ipu, pdata->di);
-       if (IS_ERR(ipu_crtc->di)) {
-               ret = PTR_ERR(ipu_crtc->di);
-               goto err_out;
-       }
-
-       return 0;
-err_out:
-       ipu_put_resources(ipu_crtc);
-
-       return ret;
-}
-
-static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
-       struct ipu_client_platformdata *pdata, struct drm_device *drm)
-{
-       struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
-       int dp = -EINVAL;
-       int ret;
-       int id;
-
-       ret = ipu_get_resources(ipu_crtc, pdata);
-       if (ret) {
-               dev_err(ipu_crtc->dev, "getting resources failed with %d.\n",
-                               ret);
-               return ret;
-       }
-
-       ret = imx_drm_add_crtc(drm, &ipu_crtc->base, &ipu_crtc->imx_crtc,
-                       &ipu_crtc_helper_funcs, ipu_crtc->dev->of_node);
-       if (ret) {
-               dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret);
-               goto err_put_resources;
-       }
-
-       if (pdata->dp >= 0)
-               dp = IPU_DP_FLOW_SYNC_BG;
-       id = imx_drm_crtc_id(ipu_crtc->imx_crtc);
-       ipu_crtc->plane[0] = ipu_plane_init(ipu_crtc->base.dev, ipu,
-                                           pdata->dma[0], dp, BIT(id), true);
-       ret = ipu_plane_get_resources(ipu_crtc->plane[0]);
-       if (ret) {
-               dev_err(ipu_crtc->dev, "getting plane 0 resources failed with %d.\n",
-                       ret);
-               goto err_remove_crtc;
-       }
-
-       /* If this crtc is using the DP, add an overlay plane */
-       if (pdata->dp >= 0 && pdata->dma[1] > 0) {
-               ipu_crtc->plane[1] = ipu_plane_init(ipu_crtc->base.dev, ipu,
-                                                   pdata->dma[1],
-                                                   IPU_DP_FLOW_SYNC_FG,
-                                                   BIT(id), false);
-               if (IS_ERR(ipu_crtc->plane[1]))
-                       ipu_crtc->plane[1] = NULL;
-       }
-
-       ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]);
-       ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0,
-                       "imx_drm", ipu_crtc);
-       if (ret < 0) {
-               dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
-               goto err_put_plane_res;
-       }
-
-       return 0;
-
-err_put_plane_res:
-       ipu_plane_put_resources(ipu_crtc->plane[0]);
-err_remove_crtc:
-       imx_drm_remove_crtc(ipu_crtc->imx_crtc);
-err_put_resources:
-       ipu_put_resources(ipu_crtc);
-
-       return ret;
-}
-
-static struct device_node *ipu_drm_get_port_by_id(struct device_node *parent,
-                                                 int port_id)
-{
-       struct device_node *port;
-       int id, ret;
-
-       port = of_get_child_by_name(parent, "port");
-       while (port) {
-               ret = of_property_read_u32(port, "reg", &id);
-               if (!ret && id == port_id)
-                       return port;
-
-               do {
-                       port = of_get_next_child(parent, port);
-                       if (!port)
-                               return NULL;
-               } while (of_node_cmp(port->name, "port"));
-       }
-
-       return NULL;
-}
-
-static int ipu_drm_bind(struct device *dev, struct device *master, void *data)
-{
-       struct ipu_client_platformdata *pdata = dev->platform_data;
-       struct drm_device *drm = data;
-       struct ipu_crtc *ipu_crtc;
-       int ret;
-
-       ipu_crtc = devm_kzalloc(dev, sizeof(*ipu_crtc), GFP_KERNEL);
-       if (!ipu_crtc)
-               return -ENOMEM;
-
-       ipu_crtc->dev = dev;
-
-       ret = ipu_crtc_init(ipu_crtc, pdata, drm);
-       if (ret)
-               return ret;
-
-       dev_set_drvdata(dev, ipu_crtc);
-
-       return 0;
-}
-
-static void ipu_drm_unbind(struct device *dev, struct device *master,
-       void *data)
-{
-       struct ipu_crtc *ipu_crtc = dev_get_drvdata(dev);
-
-       imx_drm_remove_crtc(ipu_crtc->imx_crtc);
-
-       ipu_plane_put_resources(ipu_crtc->plane[0]);
-       ipu_put_resources(ipu_crtc);
-}
-
-static const struct component_ops ipu_crtc_ops = {
-       .bind = ipu_drm_bind,
-       .unbind = ipu_drm_unbind,
-};
-
-static int ipu_drm_probe(struct platform_device *pdev)
-{
-       struct device *dev = &pdev->dev;
-       struct ipu_client_platformdata *pdata = dev->platform_data;
-       int ret;
-
-       if (!dev->platform_data)
-               return -EINVAL;
-
-       if (!dev->of_node) {
-               /* Associate crtc device with the corresponding DI port node */
-               dev->of_node = ipu_drm_get_port_by_id(dev->parent->of_node,
-                                                     pdata->di + 2);
-               if (!dev->of_node) {
-                       dev_err(dev, "missing port@%d node in %s\n",
-                               pdata->di + 2, dev->parent->of_node->full_name);
-                       return -ENODEV;
-               }
-       }
-
-       ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
-       if (ret)
-               return ret;
-
-       return component_add(dev, &ipu_crtc_ops);
-}
-
-static int ipu_drm_remove(struct platform_device *pdev)
-{
-       component_del(&pdev->dev, &ipu_crtc_ops);
-       return 0;
-}
-
-static struct platform_driver ipu_drm_driver = {
-       .driver = {
-               .name = "imx-ipuv3-crtc",
-       },
-       .probe = ipu_drm_probe,
-       .remove = ipu_drm_remove,
-};
-module_platform_driver(ipu_drm_driver);
-
-MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-ipuv3-crtc");
diff --git a/drivers/staging/imx-drm/ipuv3-plane.c b/drivers/staging/imx-drm/ipuv3-plane.c
deleted file mode 100644 (file)
index 944962b..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * i.MX IPUv3 DP Overlay Planes
- *
- * Copyright (C) 2013 Philipp Zabel, Pengutronix
- *
- * 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.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <drm/drmP.h>
-#include <drm/drm_fb_cma_helper.h>
-#include <drm/drm_gem_cma_helper.h>
-
-#include "video/imx-ipu-v3.h"
-#include "ipuv3-plane.h"
-
-#define to_ipu_plane(x)        container_of(x, struct ipu_plane, base)
-
-static const uint32_t ipu_plane_formats[] = {
-       DRM_FORMAT_XRGB1555,
-       DRM_FORMAT_XBGR1555,
-       DRM_FORMAT_ARGB8888,
-       DRM_FORMAT_XRGB8888,
-       DRM_FORMAT_ABGR8888,
-       DRM_FORMAT_XBGR8888,
-       DRM_FORMAT_YUYV,
-       DRM_FORMAT_YVYU,
-       DRM_FORMAT_YUV420,
-       DRM_FORMAT_YVU420,
-};
-
-int ipu_plane_irq(struct ipu_plane *ipu_plane)
-{
-       return ipu_idmac_channel_irq(ipu_plane->ipu, ipu_plane->ipu_ch,
-                                    IPU_IRQ_EOF);
-}
-
-static int calc_vref(struct drm_display_mode *mode)
-{
-       unsigned long htotal, vtotal;
-
-       htotal = mode->htotal;
-       vtotal = mode->vtotal;
-
-       if (!htotal || !vtotal)
-               return 60;
-
-       return DIV_ROUND_UP(mode->clock * 1000, vtotal * htotal);
-}
-
-static inline int calc_bandwidth(int width, int height, unsigned int vref)
-{
-       return width * height * vref;
-}
-
-int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb,
-                      int x, int y)
-{
-       struct drm_gem_cma_object *cma_obj;
-       unsigned long eba;
-
-       cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
-       if (!cma_obj) {
-               DRM_DEBUG_KMS("entry is null.\n");
-               return -EFAULT;
-       }
-
-       dev_dbg(ipu_plane->base.dev->dev, "phys = %pad, x = %d, y = %d",
-               &cma_obj->paddr, x, y);
-
-       ipu_cpmem_set_stride(ipu_plane->ipu_ch, fb->pitches[0]);
-
-       eba = cma_obj->paddr + fb->offsets[0] +
-             fb->pitches[0] * y + (fb->bits_per_pixel >> 3) * x;
-       ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 0, eba);
-       ipu_cpmem_set_buffer(ipu_plane->ipu_ch, 1, eba);
-
-       /* cache offsets for subsequent pageflips */
-       ipu_plane->x = x;
-       ipu_plane->y = y;
-
-       return 0;
-}
-
-int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc,
-                      struct drm_display_mode *mode,
-                      struct drm_framebuffer *fb, int crtc_x, int crtc_y,
-                      unsigned int crtc_w, unsigned int crtc_h,
-                      uint32_t src_x, uint32_t src_y,
-                      uint32_t src_w, uint32_t src_h)
-{
-       struct device *dev = ipu_plane->base.dev->dev;
-       int ret;
-
-       /* no scaling */
-       if (src_w != crtc_w || src_h != crtc_h)
-               return -EINVAL;
-
-       /* clip to crtc bounds */
-       if (crtc_x < 0) {
-               if (-crtc_x > crtc_w)
-                       return -EINVAL;
-               src_x += -crtc_x;
-               src_w -= -crtc_x;
-               crtc_w -= -crtc_x;
-               crtc_x = 0;
-       }
-       if (crtc_y < 0) {
-               if (-crtc_y > crtc_h)
-                       return -EINVAL;
-               src_y += -crtc_y;
-               src_h -= -crtc_y;
-               crtc_h -= -crtc_y;
-               crtc_y = 0;
-       }
-       if (crtc_x + crtc_w > mode->hdisplay) {
-               if (crtc_x > mode->hdisplay)
-                       return -EINVAL;
-               crtc_w = mode->hdisplay - crtc_x;
-               src_w = crtc_w;
-       }
-       if (crtc_y + crtc_h > mode->vdisplay) {
-               if (crtc_y > mode->vdisplay)
-                       return -EINVAL;
-               crtc_h = mode->vdisplay - crtc_y;
-               src_h = crtc_h;
-       }
-       /* full plane minimum width is 13 pixels */
-       if (crtc_w < 13 && (ipu_plane->dp_flow != IPU_DP_FLOW_SYNC_FG))
-               return -EINVAL;
-       if (crtc_h < 2)
-               return -EINVAL;
-
-       switch (ipu_plane->dp_flow) {
-       case IPU_DP_FLOW_SYNC_BG:
-               ret = ipu_dp_setup_channel(ipu_plane->dp,
-                               IPUV3_COLORSPACE_RGB,
-                               IPUV3_COLORSPACE_RGB);
-               if (ret) {
-                       dev_err(dev,
-                               "initializing display processor failed with %d\n",
-                               ret);
-                       return ret;
-               }
-               ipu_dp_set_global_alpha(ipu_plane->dp, 1, 0, 1);
-               break;
-       case IPU_DP_FLOW_SYNC_FG:
-               ipu_dp_setup_channel(ipu_plane->dp,
-                               ipu_drm_fourcc_to_colorspace(fb->pixel_format),
-                               IPUV3_COLORSPACE_UNKNOWN);
-               ipu_dp_set_window_pos(ipu_plane->dp, crtc_x, crtc_y);
-               break;
-       }
-
-       ret = ipu_dmfc_init_channel(ipu_plane->dmfc, crtc_w);
-       if (ret) {
-               dev_err(dev, "initializing dmfc channel failed with %d\n", ret);
-               return ret;
-       }
-
-       ret = ipu_dmfc_alloc_bandwidth(ipu_plane->dmfc,
-                       calc_bandwidth(crtc_w, crtc_h,
-                                      calc_vref(mode)), 64);
-       if (ret) {
-               dev_err(dev, "allocating dmfc bandwidth failed with %d\n", ret);
-               return ret;
-       }
-
-       ipu_cpmem_zero(ipu_plane->ipu_ch);
-       ipu_cpmem_set_resolution(ipu_plane->ipu_ch, src_w, src_h);
-       ret = ipu_cpmem_set_fmt(ipu_plane->ipu_ch, fb->pixel_format);
-       if (ret < 0) {
-               dev_err(dev, "unsupported pixel format 0x%08x\n",
-                       fb->pixel_format);
-               return ret;
-       }
-       ipu_cpmem_set_high_priority(ipu_plane->ipu_ch);
-
-       ret = ipu_plane_set_base(ipu_plane, fb, src_x, src_y);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-void ipu_plane_put_resources(struct ipu_plane *ipu_plane)
-{
-       if (!IS_ERR_OR_NULL(ipu_plane->dp))
-               ipu_dp_put(ipu_plane->dp);
-       if (!IS_ERR_OR_NULL(ipu_plane->dmfc))
-               ipu_dmfc_put(ipu_plane->dmfc);
-       if (!IS_ERR_OR_NULL(ipu_plane->ipu_ch))
-               ipu_idmac_put(ipu_plane->ipu_ch);
-}
-
-int ipu_plane_get_resources(struct ipu_plane *ipu_plane)
-{
-       int ret;
-
-       ipu_plane->ipu_ch = ipu_idmac_get(ipu_plane->ipu, ipu_plane->dma);
-       if (IS_ERR(ipu_plane->ipu_ch)) {
-               ret = PTR_ERR(ipu_plane->ipu_ch);
-               DRM_ERROR("failed to get idmac channel: %d\n", ret);
-               return ret;
-       }
-
-       ipu_plane->dmfc = ipu_dmfc_get(ipu_plane->ipu, ipu_plane->dma);
-       if (IS_ERR(ipu_plane->dmfc)) {
-               ret = PTR_ERR(ipu_plane->dmfc);
-               DRM_ERROR("failed to get dmfc: ret %d\n", ret);
-               goto err_out;
-       }
-
-       if (ipu_plane->dp_flow >= 0) {
-               ipu_plane->dp = ipu_dp_get(ipu_plane->ipu, ipu_plane->dp_flow);
-               if (IS_ERR(ipu_plane->dp)) {
-                       ret = PTR_ERR(ipu_plane->dp);
-                       DRM_ERROR("failed to get dp flow: %d\n", ret);
-                       goto err_out;
-               }
-       }
-
-       return 0;
-err_out:
-       ipu_plane_put_resources(ipu_plane);
-
-       return ret;
-}
-
-void ipu_plane_enable(struct ipu_plane *ipu_plane)
-{
-       if (ipu_plane->dp)
-               ipu_dp_enable(ipu_plane->ipu);
-       ipu_dmfc_enable_channel(ipu_plane->dmfc);
-       ipu_idmac_enable_channel(ipu_plane->ipu_ch);
-       if (ipu_plane->dp)
-               ipu_dp_enable_channel(ipu_plane->dp);
-
-       ipu_plane->enabled = true;
-}
-
-void ipu_plane_disable(struct ipu_plane *ipu_plane)
-{
-       ipu_plane->enabled = false;
-
-       ipu_idmac_wait_busy(ipu_plane->ipu_ch, 50);
-
-       if (ipu_plane->dp)
-               ipu_dp_disable_channel(ipu_plane->dp);
-       ipu_idmac_disable_channel(ipu_plane->ipu_ch);
-       ipu_dmfc_disable_channel(ipu_plane->dmfc);
-       if (ipu_plane->dp)
-               ipu_dp_disable(ipu_plane->ipu);
-}
-
-/*
- * drm_plane API
- */
-
-static int ipu_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
-                           struct drm_framebuffer *fb, int crtc_x, int crtc_y,
-                           unsigned int crtc_w, unsigned int crtc_h,
-                           uint32_t src_x, uint32_t src_y,
-                           uint32_t src_w, uint32_t src_h)
-{
-       struct ipu_plane *ipu_plane = to_ipu_plane(plane);
-       int ret = 0;
-
-       DRM_DEBUG_KMS("plane - %p\n", plane);
-
-       if (!ipu_plane->enabled)
-               ret = ipu_plane_get_resources(ipu_plane);
-       if (ret < 0)
-               return ret;
-
-       ret = ipu_plane_mode_set(ipu_plane, crtc, &crtc->hwmode, fb,
-                       crtc_x, crtc_y, crtc_w, crtc_h,
-                       src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16);
-       if (ret < 0) {
-               ipu_plane_put_resources(ipu_plane);
-               return ret;
-       }
-
-       if (crtc != plane->crtc)
-               dev_info(plane->dev->dev, "crtc change: %p -> %p\n",
-                               plane->crtc, crtc);
-       plane->crtc = crtc;
-
-       if (!ipu_plane->enabled)
-               ipu_plane_enable(ipu_plane);
-
-       return 0;
-}
-
-static int ipu_disable_plane(struct drm_plane *plane)
-{
-       struct ipu_plane *ipu_plane = to_ipu_plane(plane);
-
-       DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
-       if (ipu_plane->enabled)
-               ipu_plane_disable(ipu_plane);
-
-       ipu_plane_put_resources(ipu_plane);
-
-       return 0;
-}
-
-static void ipu_plane_destroy(struct drm_plane *plane)
-{
-       struct ipu_plane *ipu_plane = to_ipu_plane(plane);
-
-       DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
-
-       ipu_disable_plane(plane);
-       drm_plane_cleanup(plane);
-       kfree(ipu_plane);
-}
-
-static struct drm_plane_funcs ipu_plane_funcs = {
-       .update_plane   = ipu_update_plane,
-       .disable_plane  = ipu_disable_plane,
-       .destroy        = ipu_plane_destroy,
-};
-
-struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
-                                int dma, int dp, unsigned int possible_crtcs,
-                                bool priv)
-{
-       struct ipu_plane *ipu_plane;
-       int ret;
-
-       DRM_DEBUG_KMS("channel %d, dp flow %d, possible_crtcs=0x%x\n",
-                     dma, dp, possible_crtcs);
-
-       ipu_plane = kzalloc(sizeof(*ipu_plane), GFP_KERNEL);
-       if (!ipu_plane) {
-               DRM_ERROR("failed to allocate plane\n");
-               return ERR_PTR(-ENOMEM);
-       }
-
-       ipu_plane->ipu = ipu;
-       ipu_plane->dma = dma;
-       ipu_plane->dp_flow = dp;
-
-       ret = drm_plane_init(dev, &ipu_plane->base, possible_crtcs,
-                            &ipu_plane_funcs, ipu_plane_formats,
-                            ARRAY_SIZE(ipu_plane_formats),
-                            priv);
-       if (ret) {
-               DRM_ERROR("failed to initialize plane\n");
-               kfree(ipu_plane);
-               return ERR_PTR(ret);
-       }
-
-       return ipu_plane;
-}
diff --git a/drivers/staging/imx-drm/ipuv3-plane.h b/drivers/staging/imx-drm/ipuv3-plane.h
deleted file mode 100644 (file)
index c0aae5b..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef __IPUV3_PLANE_H__
-#define __IPUV3_PLANE_H__
-
-#include <drm/drm_crtc.h> /* drm_plane */
-
-struct drm_plane;
-struct drm_device;
-struct ipu_soc;
-struct drm_crtc;
-struct drm_framebuffer;
-
-struct ipuv3_channel;
-struct dmfc_channel;
-struct ipu_dp;
-
-struct ipu_plane {
-       struct drm_plane        base;
-
-       struct ipu_soc          *ipu;
-       struct ipuv3_channel    *ipu_ch;
-       struct dmfc_channel     *dmfc;
-       struct ipu_dp           *dp;
-
-       int                     dma;
-       int                     dp_flow;
-
-       int                     x;
-       int                     y;
-
-       bool                    enabled;
-};
-
-struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu,
-                                int dma, int dp, unsigned int possible_crtcs,
-                                bool priv);
-
-/* Init IDMAC, DMFC, DP */
-int ipu_plane_mode_set(struct ipu_plane *plane, struct drm_crtc *crtc,
-                      struct drm_display_mode *mode,
-                      struct drm_framebuffer *fb, int crtc_x, int crtc_y,
-                      unsigned int crtc_w, unsigned int crtc_h,
-                      uint32_t src_x, uint32_t src_y, uint32_t src_w,
-                      uint32_t src_h);
-
-void ipu_plane_enable(struct ipu_plane *plane);
-void ipu_plane_disable(struct ipu_plane *plane);
-int ipu_plane_set_base(struct ipu_plane *plane, struct drm_framebuffer *fb,
-                      int x, int y);
-
-int ipu_plane_get_resources(struct ipu_plane *plane);
-void ipu_plane_put_resources(struct ipu_plane *plane);
-
-int ipu_plane_irq(struct ipu_plane *plane);
-
-#endif
diff --git a/drivers/staging/imx-drm/parallel-display.c b/drivers/staging/imx-drm/parallel-display.c
deleted file mode 100644 (file)
index 015a454..0000000
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * i.MX drm driver - parallel display implementation
- *
- * Copyright (C) 2012 Sascha Hauer, Pengutronix
- *
- * 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.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/component.h>
-#include <linux/module.h>
-#include <drm/drmP.h>
-#include <drm/drm_fb_helper.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_panel.h>
-#include <linux/videodev2.h>
-#include <video/of_display_timing.h>
-
-#include "imx-drm.h"
-
-#define con_to_imxpd(x) container_of(x, struct imx_parallel_display, connector)
-#define enc_to_imxpd(x) container_of(x, struct imx_parallel_display, encoder)
-
-struct imx_parallel_display {
-       struct drm_connector connector;
-       struct drm_encoder encoder;
-       struct device *dev;
-       void *edid;
-       int edid_len;
-       u32 interface_pix_fmt;
-       int mode_valid;
-       struct drm_display_mode mode;
-       struct drm_panel *panel;
-};
-
-static enum drm_connector_status imx_pd_connector_detect(
-               struct drm_connector *connector, bool force)
-{
-       return connector_status_connected;
-}
-
-static int imx_pd_connector_get_modes(struct drm_connector *connector)
-{
-       struct imx_parallel_display *imxpd = con_to_imxpd(connector);
-       struct device_node *np = imxpd->dev->of_node;
-       int num_modes = 0;
-
-       if (imxpd->panel && imxpd->panel->funcs &&
-           imxpd->panel->funcs->get_modes) {
-               num_modes = imxpd->panel->funcs->get_modes(imxpd->panel);
-               if (num_modes > 0)
-                       return num_modes;
-       }
-
-       if (imxpd->edid) {
-               drm_mode_connector_update_edid_property(connector, imxpd->edid);
-               num_modes = drm_add_edid_modes(connector, imxpd->edid);
-       }
-
-       if (imxpd->mode_valid) {
-               struct drm_display_mode *mode = drm_mode_create(connector->dev);
-
-               if (!mode)
-                       return -EINVAL;
-               drm_mode_copy(mode, &imxpd->mode);
-               mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
-               drm_mode_probed_add(connector, mode);
-               num_modes++;
-       }
-
-       if (np) {
-               struct drm_display_mode *mode = drm_mode_create(connector->dev);
-
-               if (!mode)
-                       return -EINVAL;
-               of_get_drm_display_mode(np, &imxpd->mode, OF_USE_NATIVE_MODE);
-               drm_mode_copy(mode, &imxpd->mode);
-               mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
-               drm_mode_probed_add(connector, mode);
-               num_modes++;
-       }
-
-       return num_modes;
-}
-
-static struct drm_encoder *imx_pd_connector_best_encoder(
-               struct drm_connector *connector)
-{
-       struct imx_parallel_display *imxpd = con_to_imxpd(connector);
-
-       return &imxpd->encoder;
-}
-
-static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-       struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
-
-       if (mode != DRM_MODE_DPMS_ON)
-               drm_panel_disable(imxpd->panel);
-       else
-               drm_panel_enable(imxpd->panel);
-}
-
-static bool imx_pd_encoder_mode_fixup(struct drm_encoder *encoder,
-                          const struct drm_display_mode *mode,
-                          struct drm_display_mode *adjusted_mode)
-{
-       return true;
-}
-
-static void imx_pd_encoder_prepare(struct drm_encoder *encoder)
-{
-       struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
-
-       imx_drm_panel_format(encoder, imxpd->interface_pix_fmt);
-}
-
-static void imx_pd_encoder_commit(struct drm_encoder *encoder)
-{
-}
-
-static void imx_pd_encoder_mode_set(struct drm_encoder *encoder,
-                        struct drm_display_mode *mode,
-                        struct drm_display_mode *adjusted_mode)
-{
-}
-
-static void imx_pd_encoder_disable(struct drm_encoder *encoder)
-{
-}
-
-static struct drm_connector_funcs imx_pd_connector_funcs = {
-       .dpms = drm_helper_connector_dpms,
-       .fill_modes = drm_helper_probe_single_connector_modes,
-       .detect = imx_pd_connector_detect,
-       .destroy = imx_drm_connector_destroy,
-};
-
-static struct drm_connector_helper_funcs imx_pd_connector_helper_funcs = {
-       .get_modes = imx_pd_connector_get_modes,
-       .best_encoder = imx_pd_connector_best_encoder,
-};
-
-static struct drm_encoder_funcs imx_pd_encoder_funcs = {
-       .destroy = imx_drm_encoder_destroy,
-};
-
-static struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = {
-       .dpms = imx_pd_encoder_dpms,
-       .mode_fixup = imx_pd_encoder_mode_fixup,
-       .prepare = imx_pd_encoder_prepare,
-       .commit = imx_pd_encoder_commit,
-       .mode_set = imx_pd_encoder_mode_set,
-       .disable = imx_pd_encoder_disable,
-};
-
-static int imx_pd_register(struct drm_device *drm,
-       struct imx_parallel_display *imxpd)
-{
-       int ret;
-
-       ret = imx_drm_encoder_parse_of(drm, &imxpd->encoder,
-                                      imxpd->dev->of_node);
-       if (ret)
-               return ret;
-
-       /* set the connector's dpms to OFF so that
-        * drm_helper_connector_dpms() won't return
-        * immediately since the current state is ON
-        * at this point.
-        */
-       imxpd->connector.dpms = DRM_MODE_DPMS_OFF;
-
-       drm_encoder_helper_add(&imxpd->encoder, &imx_pd_encoder_helper_funcs);
-       drm_encoder_init(drm, &imxpd->encoder, &imx_pd_encoder_funcs,
-                        DRM_MODE_ENCODER_NONE);
-
-       drm_connector_helper_add(&imxpd->connector,
-                       &imx_pd_connector_helper_funcs);
-       drm_connector_init(drm, &imxpd->connector, &imx_pd_connector_funcs,
-                          DRM_MODE_CONNECTOR_VGA);
-
-       if (imxpd->panel)
-               drm_panel_attach(imxpd->panel, &imxpd->connector);
-
-       drm_mode_connector_attach_encoder(&imxpd->connector, &imxpd->encoder);
-
-       imxpd->connector.encoder = &imxpd->encoder;
-
-       return 0;
-}
-
-static int imx_pd_bind(struct device *dev, struct device *master, void *data)
-{
-       struct drm_device *drm = data;
-       struct device_node *np = dev->of_node;
-       struct device_node *panel_node;
-       const u8 *edidp;
-       struct imx_parallel_display *imxpd;
-       int ret;
-       const char *fmt;
-
-       imxpd = devm_kzalloc(dev, sizeof(*imxpd), GFP_KERNEL);
-       if (!imxpd)
-               return -ENOMEM;
-
-       edidp = of_get_property(np, "edid", &imxpd->edid_len);
-       if (edidp)
-               imxpd->edid = kmemdup(edidp, imxpd->edid_len, GFP_KERNEL);
-
-       ret = of_property_read_string(np, "interface-pix-fmt", &fmt);
-       if (!ret) {
-               if (!strcmp(fmt, "rgb24"))
-                       imxpd->interface_pix_fmt = V4L2_PIX_FMT_RGB24;
-               else if (!strcmp(fmt, "rgb565"))
-                       imxpd->interface_pix_fmt = V4L2_PIX_FMT_RGB565;
-               else if (!strcmp(fmt, "bgr666"))
-                       imxpd->interface_pix_fmt = V4L2_PIX_FMT_BGR666;
-               else if (!strcmp(fmt, "lvds666"))
-                       imxpd->interface_pix_fmt =
-                                       v4l2_fourcc('L', 'V', 'D', '6');
-       }
-
-       panel_node = of_parse_phandle(np, "fsl,panel", 0);
-       if (panel_node)
-               imxpd->panel = of_drm_find_panel(panel_node);
-
-       imxpd->dev = dev;
-
-       ret = imx_pd_register(drm, imxpd);
-       if (ret)
-               return ret;
-
-       dev_set_drvdata(dev, imxpd);
-
-       return 0;
-}
-
-static void imx_pd_unbind(struct device *dev, struct device *master,
-       void *data)
-{
-       struct imx_parallel_display *imxpd = dev_get_drvdata(dev);
-
-       imxpd->encoder.funcs->destroy(&imxpd->encoder);
-       imxpd->connector.funcs->destroy(&imxpd->connector);
-}
-
-static const struct component_ops imx_pd_ops = {
-       .bind   = imx_pd_bind,
-       .unbind = imx_pd_unbind,
-};
-
-static int imx_pd_probe(struct platform_device *pdev)
-{
-       return component_add(&pdev->dev, &imx_pd_ops);
-}
-
-static int imx_pd_remove(struct platform_device *pdev)
-{
-       component_del(&pdev->dev, &imx_pd_ops);
-       return 0;
-}
-
-static const struct of_device_id imx_pd_dt_ids[] = {
-       { .compatible = "fsl,imx-parallel-display", },
-       { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, imx_pd_dt_ids);
-
-static struct platform_driver imx_pd_driver = {
-       .probe          = imx_pd_probe,
-       .remove         = imx_pd_remove,
-       .driver         = {
-               .of_match_table = imx_pd_dt_ids,
-               .name   = "imx-parallel-display",
-               .owner  = THIS_MODULE,
-       },
-};
-
-module_platform_driver(imx_pd_driver);
-
-MODULE_DESCRIPTION("i.MX parallel display driver");
-MODULE_AUTHOR("Sascha Hauer, Pengutronix");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:imx-parallel-display");