]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00273848-02 iMX6Q/DL HDMI: Enable HDMI function
authorSandor Yu <R01008@freescale.com>
Mon, 5 Aug 2013 08:12:53 +0000 (16:12 +0800)
committerJason Liu <r64343@freescale.com>
Wed, 30 Oct 2013 01:54:16 +0000 (09:54 +0800)
Add MX6Q/DL HDMI core and video driver source code.
Add MXC edid data read and parse source code.

Signed-off-by: Sandor Yu <R01008@freescale.com>
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/mxc-hdmi-core.c [new file with mode: 0644]
drivers/video/mxc/Kconfig
drivers/video/mxc/Makefile
drivers/video/mxc/mxc_edid.c [new file with mode: 0644]
drivers/video/mxc/mxc_hdmi.c [new file with mode: 0644]
include/linux/mfd/mxc-hdmi-core.h [new file with mode: 0644]
include/video/mxc_edid.h [new file with mode: 0755]
include/video/mxc_hdmi.h [new file with mode: 0644]

index d54e985748b78403956a0b7ba0d2b8634b949244..043901b09dca8b764f67553402f2962519d88586 100644 (file)
@@ -1148,3 +1148,11 @@ config VEXPRESS_CONFIG
        help
          Platform configuration infrastructure for the ARM Ltd.
          Versatile Express.
+
+config MFD_MXC_HDMI
+       tristate "MXC HDMI Core"
+       select MFD_CORE
+       default y
+       help
+         This is the core driver for the i.MX on-chip HDMI.  This MFD
+         driver connects with the video and audio drivers for HDMI.
index 718e94a2a9a7577e5bb6f286c822983c88e2dcf7..41ab2b45e1880fa92718b9abd94c45c4b5ceb7d9 100644 (file)
@@ -155,3 +155,4 @@ obj-$(CONFIG_MFD_LM3533)    += lm3533-core.o lm3533-ctrlbank.o
 obj-$(CONFIG_VEXPRESS_CONFIG)  += vexpress-config.o vexpress-sysreg.o
 obj-$(CONFIG_MFD_RETU)         += retu-mfd.o
 obj-$(CONFIG_MFD_AS3711)       += as3711.o
+obj-$(CONFIG_MFD_MXC_HDMI)       += mxc-hdmi-core.o
diff --git a/drivers/mfd/mxc-hdmi-core.c b/drivers/mfd/mxc-hdmi-core.c
new file mode 100644 (file)
index 0000000..7da0bf6
--- /dev/null
@@ -0,0 +1,785 @@
+/*
+ * 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.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <asm/mach-types.h>
+
+#include <video/mxc_hdmi.h>
+#include <linux/ipu-v3.h>
+#include <video/mxc_edid.h>
+#include "../mxc/ipu3/ipu_prv.h"
+#include <linux/mfd/mxc-hdmi-core.h>
+#include <linux/of_device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/mfd/mxc-hdmi-core.h>
+
+struct mxc_hdmi_data {
+       struct platform_device *pdev;
+       unsigned long __iomem *reg_base;
+       unsigned long reg_phys_base;
+       struct device *dev;
+};
+
+static void __iomem *hdmi_base;
+static struct clk *isfr_clk;
+static struct clk *iahb_clk;
+static spinlock_t irq_spinlock;
+static spinlock_t edid_spinlock;
+static unsigned int sample_rate;
+static unsigned long pixel_clk_rate;
+static struct clk *pixel_clk;
+static int hdmi_ratio;
+int mxc_hdmi_ipu_id;
+int mxc_hdmi_disp_id;
+static struct mxc_edid_cfg hdmi_core_edid_cfg;
+static int hdmi_core_init;
+static unsigned int hdmi_dma_running;
+static struct snd_pcm_substream *hdmi_audio_stream_playback;
+static unsigned int hdmi_cable_state;
+static unsigned int hdmi_blank_state;
+static spinlock_t hdmi_audio_lock, hdmi_blank_state_lock, hdmi_cable_state_lock;
+
+unsigned int hdmi_set_cable_state(unsigned int state)
+{
+       unsigned long flags;
+       struct snd_pcm_substream *substream = hdmi_audio_stream_playback;
+
+       spin_lock_irqsave(&hdmi_cable_state_lock, flags);
+       hdmi_cable_state = state;
+       spin_unlock_irqrestore(&hdmi_cable_state_lock, flags);
+
+       if (check_hdmi_state() && substream)
+               substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
+       return 0;
+}
+EXPORT_SYMBOL(hdmi_set_cable_state);
+
+unsigned int hdmi_set_blank_state(unsigned int state)
+{
+       unsigned long flags;
+       struct snd_pcm_substream *substream = hdmi_audio_stream_playback;
+
+       spin_lock_irqsave(&hdmi_blank_state_lock, flags);
+       hdmi_blank_state = state;
+       spin_unlock_irqrestore(&hdmi_blank_state_lock, flags);
+
+       if (check_hdmi_state() && substream)
+               substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
+
+       return 0;
+}
+EXPORT_SYMBOL(hdmi_set_blank_state);
+
+static void hdmi_audio_abort_stream(struct snd_pcm_substream *substream)
+{
+       unsigned long flags;
+
+       snd_pcm_stream_lock_irqsave(substream, flags);
+
+       if (snd_pcm_running(substream))
+               substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
+
+       snd_pcm_stream_unlock_irqrestore(substream, flags);
+}
+
+int mxc_hdmi_abort_stream(void)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&hdmi_audio_lock, flags);
+       if (hdmi_audio_stream_playback)
+               hdmi_audio_abort_stream(hdmi_audio_stream_playback);
+       spin_unlock_irqrestore(&hdmi_audio_lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL(mxc_hdmi_abort_stream);
+
+int check_hdmi_state(void)
+{
+       unsigned long flags1, flags2;
+       unsigned int ret;
+
+       spin_lock_irqsave(&hdmi_cable_state_lock, flags1);
+       spin_lock_irqsave(&hdmi_blank_state_lock, flags2);
+
+       ret = hdmi_cable_state && hdmi_blank_state;
+
+       spin_unlock_irqrestore(&hdmi_blank_state_lock, flags2);
+       spin_unlock_irqrestore(&hdmi_cable_state_lock, flags1);
+
+       return ret;
+}
+EXPORT_SYMBOL(check_hdmi_state);
+
+int mxc_hdmi_register_audio(struct snd_pcm_substream *substream)
+{
+       unsigned long flags, flags1;
+       int ret = 0;
+
+       snd_pcm_stream_lock_irqsave(substream, flags);
+
+       if (substream && check_hdmi_state()) {
+               spin_lock_irqsave(&hdmi_audio_lock, flags1);
+               if (hdmi_audio_stream_playback) {
+                       pr_err("%s unconsist hdmi auido stream!\n", __func__);
+                       ret = -EINVAL;
+               }
+               hdmi_audio_stream_playback = substream;
+               spin_unlock_irqrestore(&hdmi_audio_lock, flags1);
+       } else
+               ret = -EINVAL;
+
+       snd_pcm_stream_unlock_irqrestore(substream, flags);
+
+       return ret;
+}
+EXPORT_SYMBOL(mxc_hdmi_register_audio);
+
+void mxc_hdmi_unregister_audio(struct snd_pcm_substream *substream)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&hdmi_audio_lock, flags);
+       hdmi_audio_stream_playback = NULL;
+       spin_unlock_irqrestore(&hdmi_audio_lock, flags);
+}
+EXPORT_SYMBOL(mxc_hdmi_unregister_audio);
+
+u8 hdmi_readb(unsigned int reg)
+{
+       u8 value;
+
+       value = __raw_readb(hdmi_base + reg);
+
+       return value;
+}
+EXPORT_SYMBOL(hdmi_readb);
+
+#ifdef DEBUG
+static bool overflow_lo;
+static bool overflow_hi;
+
+bool hdmi_check_overflow(void)
+{
+       u8 val, lo, hi;
+
+       val = hdmi_readb(HDMI_IH_FC_STAT2);
+       lo = (val & HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW) != 0;
+       hi = (val & HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW) != 0;
+
+       if ((lo != overflow_lo) || (hi != overflow_hi)) {
+               pr_debug("%s LowPriority=%d HighPriority=%d  <=======================\n",
+                       __func__, lo, hi);
+               overflow_lo = lo;
+               overflow_hi = hi;
+               return true;
+       }
+       return false;
+}
+#else
+bool hdmi_check_overflow(void)
+{
+       return false;
+}
+#endif
+EXPORT_SYMBOL(hdmi_check_overflow);
+
+void hdmi_writeb(u8 value, unsigned int reg)
+{
+       hdmi_check_overflow();
+       __raw_writeb(value, hdmi_base + reg);
+       hdmi_check_overflow();
+}
+EXPORT_SYMBOL(hdmi_writeb);
+
+void hdmi_mask_writeb(u8 data, unsigned int reg, u8 shift, u8 mask)
+{
+       u8 value = hdmi_readb(reg) & ~mask;
+       value |= (data << shift) & mask;
+       hdmi_writeb(value, reg);
+}
+EXPORT_SYMBOL(hdmi_mask_writeb);
+
+unsigned int hdmi_read4(unsigned int reg)
+{
+       /* read a four byte address from registers */
+       return (hdmi_readb(reg + 3) << 24) |
+               (hdmi_readb(reg + 2) << 16) |
+               (hdmi_readb(reg + 1) << 8) |
+               hdmi_readb(reg);
+}
+EXPORT_SYMBOL(hdmi_read4);
+
+void hdmi_write4(unsigned int value, unsigned int reg)
+{
+       /* write a four byte address to hdmi regs */
+       hdmi_writeb(value & 0xff, reg);
+       hdmi_writeb((value >> 8) & 0xff, reg + 1);
+       hdmi_writeb((value >> 16) & 0xff, reg + 2);
+       hdmi_writeb((value >> 24) & 0xff, reg + 3);
+}
+EXPORT_SYMBOL(hdmi_write4);
+
+static void initialize_hdmi_ih_mutes(void)
+{
+       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_IH_MUTE) |
+                 HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
+                 HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;
+
+       hdmi_writeb(ih_mute, HDMI_IH_MUTE);
+
+       /* by default mask all interrupts */
+       hdmi_writeb(0xff, HDMI_VP_MASK);
+       hdmi_writeb(0xff, HDMI_FC_MASK0);
+       hdmi_writeb(0xff, HDMI_FC_MASK1);
+       hdmi_writeb(0xff, HDMI_FC_MASK2);
+       hdmi_writeb(0xff, HDMI_PHY_MASK0);
+       hdmi_writeb(0xff, HDMI_PHY_I2CM_INT_ADDR);
+       hdmi_writeb(0xff, HDMI_PHY_I2CM_CTLINT_ADDR);
+       hdmi_writeb(0xff, HDMI_AUD_INT);
+       hdmi_writeb(0xff, HDMI_AUD_SPDIFINT);
+       hdmi_writeb(0xff, HDMI_AUD_HBR_MASK);
+       hdmi_writeb(0xff, HDMI_GP_MASK);
+       hdmi_writeb(0xff, HDMI_A_APIINTMSK);
+       hdmi_writeb(0xff, HDMI_CEC_MASK);
+       hdmi_writeb(0xff, HDMI_I2CM_INT);
+       hdmi_writeb(0xff, HDMI_I2CM_CTLINT);
+
+       /* Disable interrupts in the IH_MUTE_* registers */
+       hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT0);
+       hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT1);
+       hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT2);
+       hdmi_writeb(0xff, HDMI_IH_MUTE_AS_STAT0);
+       hdmi_writeb(0xff, HDMI_IH_MUTE_PHY_STAT0);
+       hdmi_writeb(0xff, HDMI_IH_MUTE_I2CM_STAT0);
+       hdmi_writeb(0xff, HDMI_IH_MUTE_CEC_STAT0);
+       hdmi_writeb(0xff, HDMI_IH_MUTE_VP_STAT0);
+       hdmi_writeb(0xff, HDMI_IH_MUTE_I2CMPHY_STAT0);
+       hdmi_writeb(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(ih_mute, HDMI_IH_MUTE);
+}
+
+static void hdmi_set_clock_regenerator_n(unsigned int value)
+{
+       u8 val;
+
+       if (!hdmi_dma_running) {
+               hdmi_writeb(value & 0xff, HDMI_AUD_N1);
+               hdmi_writeb(0, HDMI_AUD_N2);
+               hdmi_writeb(0, HDMI_AUD_N3);
+       }
+
+       hdmi_writeb(value & 0xff, HDMI_AUD_N1);
+       hdmi_writeb((value >> 8) & 0xff, HDMI_AUD_N2);
+       hdmi_writeb((value >> 16) & 0x0f, HDMI_AUD_N3);
+
+       /* nshift factor = 0 */
+       val = hdmi_readb(HDMI_AUD_CTS3);
+       val &= ~HDMI_AUD_CTS3_N_SHIFT_MASK;
+       hdmi_writeb(val, HDMI_AUD_CTS3);
+}
+
+static void hdmi_set_clock_regenerator_cts(unsigned int cts)
+{
+       u8 val;
+
+       if (!hdmi_dma_running) {
+               hdmi_writeb(cts & 0xff, HDMI_AUD_CTS1);
+               hdmi_writeb(0, HDMI_AUD_CTS2);
+               hdmi_writeb(0, HDMI_AUD_CTS3);
+       }
+
+       /* Must be set/cleared first */
+       val = hdmi_readb(HDMI_AUD_CTS3);
+       val &= ~HDMI_AUD_CTS3_CTS_MANUAL;
+       hdmi_writeb(val, HDMI_AUD_CTS3);
+
+       hdmi_writeb(cts & 0xff, HDMI_AUD_CTS1);
+       hdmi_writeb((cts >> 8) & 0xff, HDMI_AUD_CTS2);
+       hdmi_writeb(((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 == 25174000)
+                       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 if (pixel_clk == 297000000)
+                       n = (ratio == 150) ? 6144 : 3072;
+               else
+                       n = 4096;
+               break;
+
+       case 44100:
+               if (pixel_clk == 25174000)
+                       n = 7007;
+               else if (pixel_clk == 74170000)
+                       n = 17836;
+               else if (pixel_clk == 148350000)
+                       n = (ratio == 150) ? 17836 : 8918;
+               else if (pixel_clk == 297000000)
+                       n = (ratio == 150) ? 9408 : 4704;
+               else
+                       n = 6272;
+               break;
+
+       case 48000:
+               if (pixel_clk == 25174000)
+                       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 if (pixel_clk == 297000000)
+                       n = (ratio == 150) ? 10240 : 5120;
+               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;
+       switch (freq) {
+       case 32000:
+               if (pixel_clk == 297000000) {
+                       cts = 222750;
+                       break;
+               } else if (pixel_clk == 25174000) {
+                       cts = 28125;
+                       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;
+               case 25174000:
+                       cts = 28125l;
+                       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 25174000:
+                       cts = 31250;
+                       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;
+       else
+               return (cts * ratio) / 100;
+}
+
+static void hdmi_set_clk_regenerator(void)
+{
+       unsigned int clk_n, clk_cts;
+
+       clk_n = hdmi_compute_n(sample_rate, pixel_clk_rate, hdmi_ratio);
+       clk_cts = hdmi_compute_cts(sample_rate, pixel_clk_rate, hdmi_ratio);
+
+       if (clk_cts == 0) {
+               pr_debug("%s: pixel clock not supported: %d\n",
+                       __func__, (int)pixel_clk_rate);
+               return;
+       }
+
+       pr_debug("%s: samplerate=%d  ratio=%d  pixelclk=%d  N=%d  cts=%d\n",
+               __func__, sample_rate, hdmi_ratio, (int)pixel_clk_rate,
+               clk_n, clk_cts);
+
+       hdmi_set_clock_regenerator_cts(clk_cts);
+       hdmi_set_clock_regenerator_n(clk_n);
+}
+
+static int hdmi_core_get_of_property(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       int err;
+       int ipu_id, disp_id;
+
+       err = of_property_read_u32(np, "ipu_id", &ipu_id);
+       if (err) {
+               dev_dbg(&pdev->dev, "get of property ipu_id fail\n");
+               return err;
+       }
+       err = of_property_read_u32(np, "disp_id", &disp_id);
+       if (err) {
+               dev_dbg(&pdev->dev, "get of property disp_id fail\n");
+               return err;
+       }
+
+       mxc_hdmi_ipu_id = ipu_id;
+       mxc_hdmi_disp_id = disp_id;
+
+       return err;
+}
+/*
+unsigned int hdmi_SDMA_check(void)
+{
+
+       return (imx6q_revision() > IMX_CHIP_REVISION_1_1) ||
+                       (imx6dl_revision() > IMX_CHIP_REVISION_1_0);
+
+       return 0;
+}
+EXPORT_SYMBOL(hdmi_SDMA_check);
+*/
+/* Need to run this before phy is enabled the first time to prevent
+ * overflow condition in HDMI_IH_FC_STAT2 */
+void hdmi_init_clk_regenerator(void)
+{
+       if (pixel_clk_rate == 0) {
+               pixel_clk_rate = 74250000;
+               hdmi_set_clk_regenerator();
+       }
+}
+EXPORT_SYMBOL(hdmi_init_clk_regenerator);
+
+void hdmi_clk_regenerator_update_pixel_clock(u32 pixclock)
+{
+
+       /* Translate pixel clock in ps (pico seconds) to Hz  */
+       pixel_clk_rate = PICOS2KHZ(pixclock) * 1000UL;
+       hdmi_set_clk_regenerator();
+}
+EXPORT_SYMBOL(hdmi_clk_regenerator_update_pixel_clock);
+
+void hdmi_set_dma_mode(unsigned int dma_running)
+{
+       hdmi_dma_running = dma_running;
+       hdmi_set_clk_regenerator();
+}
+EXPORT_SYMBOL(hdmi_set_dma_mode);
+
+void hdmi_set_sample_rate(unsigned int rate)
+{
+       sample_rate = rate;
+}
+EXPORT_SYMBOL(hdmi_set_sample_rate);
+
+void hdmi_set_edid_cfg(struct mxc_edid_cfg *cfg)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&edid_spinlock, flags);
+       memcpy(&hdmi_core_edid_cfg, cfg, sizeof(struct mxc_edid_cfg));
+       spin_unlock_irqrestore(&edid_spinlock, flags);
+}
+EXPORT_SYMBOL(hdmi_set_edid_cfg);
+
+void hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&edid_spinlock, flags);
+       memcpy(cfg, &hdmi_core_edid_cfg, sizeof(struct mxc_edid_cfg));
+       spin_unlock_irqrestore(&edid_spinlock, flags);
+}
+EXPORT_SYMBOL(hdmi_get_edid_cfg);
+
+void hdmi_set_registered(int registered)
+{
+       hdmi_core_init = registered;
+}
+EXPORT_SYMBOL(hdmi_set_registered);
+
+int hdmi_get_registered(void)
+{
+       return hdmi_core_init;
+}
+EXPORT_SYMBOL(hdmi_get_registered);
+
+static int mxc_hdmi_core_probe(struct platform_device *pdev)
+{
+       struct mxc_hdmi_data *hdmi_data;
+       struct resource *res;
+       unsigned long flags;
+       int ret = 0;
+
+#ifdef DEBUG
+       overflow_lo = false;
+       overflow_hi = false;
+#endif
+
+       hdmi_core_init = 0;
+       hdmi_dma_running = 0;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENOENT;
+
+       ret = hdmi_core_get_of_property(pdev);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "get hdmi of property fail\n");
+               return -ENOENT;
+       }
+
+       hdmi_data = devm_kzalloc(&pdev->dev, sizeof(struct mxc_hdmi_data), GFP_KERNEL);
+       if (!hdmi_data) {
+               dev_err(&pdev->dev, "Couldn't allocate mxc hdmi mfd device\n");
+               return -ENOMEM;
+       }
+       hdmi_data->pdev = pdev;
+
+       pixel_clk = NULL;
+       sample_rate = 48000;
+       pixel_clk_rate = 0;
+       hdmi_ratio = 100;
+
+       spin_lock_init(&irq_spinlock);
+       spin_lock_init(&edid_spinlock);
+
+
+       spin_lock_init(&hdmi_cable_state_lock);
+       spin_lock_init(&hdmi_blank_state_lock);
+       spin_lock_init(&hdmi_audio_lock);
+
+       spin_lock_irqsave(&hdmi_cable_state_lock, flags);
+       hdmi_cable_state = 0;
+       spin_unlock_irqrestore(&hdmi_cable_state_lock, flags);
+
+       spin_lock_irqsave(&hdmi_blank_state_lock, flags);
+       hdmi_blank_state = 0;
+       spin_unlock_irqrestore(&hdmi_blank_state_lock, flags);
+
+       spin_lock_irqsave(&hdmi_audio_lock, flags);
+       hdmi_audio_stream_playback = NULL;
+       spin_unlock_irqrestore(&hdmi_audio_lock, flags);
+
+       isfr_clk = clk_get(&hdmi_data->pdev->dev, "hdmi_isfr");
+       if (IS_ERR(isfr_clk)) {
+               ret = PTR_ERR(isfr_clk);
+               dev_err(&hdmi_data->pdev->dev,
+                       "Unable to get HDMI isfr clk: %d\n", ret);
+               goto eclkg;
+       }
+
+       ret = clk_prepare_enable(isfr_clk);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Cannot enable HDMI clock: %d\n", ret);
+               goto eclke;
+       }
+
+       pr_debug("%s isfr_clk:%d\n", __func__,
+               (int)clk_get_rate(isfr_clk));
+
+       iahb_clk = clk_get(&hdmi_data->pdev->dev, "hdmi_iahb");
+       if (IS_ERR(iahb_clk)) {
+               ret = PTR_ERR(iahb_clk);
+               dev_err(&hdmi_data->pdev->dev,
+                       "Unable to get HDMI iahb clk: %d\n", ret);
+               goto eclkg2;
+       }
+
+       ret = clk_prepare_enable(iahb_clk);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Cannot enable HDMI clock: %d\n", ret);
+               goto eclke2;
+       }
+
+       hdmi_data->reg_phys_base = res->start;
+       if (!request_mem_region(res->start, resource_size(res),
+                               dev_name(&pdev->dev))) {
+               dev_err(&pdev->dev, "request_mem_region failed\n");
+               ret = -EBUSY;
+               goto emem;
+       }
+
+       hdmi_data->reg_base = ioremap(res->start, resource_size(res));
+       if (!hdmi_data->reg_base) {
+               dev_err(&pdev->dev, "ioremap failed\n");
+               ret = -ENOMEM;
+               goto eirq;
+       }
+       hdmi_base = hdmi_data->reg_base;
+
+       pr_debug("\n%s hdmi hw base = 0x%08x\n\n", __func__, (int)res->start);
+
+       initialize_hdmi_ih_mutes();
+
+       /* Disable HDMI clocks until video/audio sub-drivers are initialized */
+       clk_disable_unprepare(isfr_clk);
+       clk_disable_unprepare(iahb_clk);
+
+       /* Replace platform data coming in with a local struct */
+       platform_set_drvdata(pdev, hdmi_data);
+
+       return ret;
+
+eirq:
+       release_mem_region(res->start, resource_size(res));
+emem:
+       clk_disable_unprepare(iahb_clk);
+eclke2:
+       clk_put(iahb_clk);
+eclkg2:
+       clk_disable_unprepare(isfr_clk);
+eclke:
+       clk_put(isfr_clk);
+eclkg:
+       return ret;
+}
+
+
+static int __exit mxc_hdmi_core_remove(struct platform_device *pdev)
+{
+       struct mxc_hdmi_data *hdmi_data = platform_get_drvdata(pdev);
+       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       iounmap(hdmi_data->reg_base);
+       release_mem_region(res->start, resource_size(res));
+
+       return 0;
+}
+
+static const struct of_device_id imx_hdmi_dt_ids[] = {
+       { .compatible = "fsl,imx6q-hdmi-core", },
+       { .compatible = "fsl,imx6dl-hdmi-core", },
+       { /* sentinel */ }
+};
+
+static struct platform_driver mxc_hdmi_core_driver = {
+       .driver = {
+               .name = "mxc_hdmi_core",
+               .of_match_table = imx_hdmi_dt_ids,
+               .owner = THIS_MODULE,
+       },
+       .remove = __exit_p(mxc_hdmi_core_remove),
+};
+
+static int __init mxc_hdmi_core_init(void)
+{
+       return platform_driver_probe(&mxc_hdmi_core_driver,
+                                    mxc_hdmi_core_probe);
+}
+
+static void __exit mxc_hdmi_core_exit(void)
+{
+       platform_driver_unregister(&mxc_hdmi_core_driver);
+}
+
+subsys_initcall(mxc_hdmi_core_init);
+module_exit(mxc_hdmi_core_exit);
+
+MODULE_DESCRIPTION("Core driver for Freescale i.Mx on-chip HDMI");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_LICENSE("GPL");
index 0b4eaa97e0943b565c222539856e7931e8ca6e03..3e4dcb1a6dea8d6e28f95b5536ab49c989211cb7 100644 (file)
@@ -22,3 +22,17 @@ config FB_MXC_LDB
        tristate "MXC LDB"
        depends on FB_MXC_SYNC_PANEL
        depends on MXC_IPU_V3
+
+config FB_MXC_HDMI
+       depends on FB_MXC_SYNC_PANEL
+       depends on MXC_IPU_V3
+       depends on I2C
+       tristate "MXC HDMI driver support"
+       select MFD_MXC_HDMI
+       help
+         Driver for the on-chip MXC HDMI controller.
+
+config FB_MXC_EDID
+     depends on FB_MXC && I2C
+     tristate "MXC EDID support"
+     default y
index 5fc36bbf6ef32c6cc5250786b4650ff04ee1e13d..b6148e81ca722235bf0bef987d4fcbabae34fabf 100644 (file)
@@ -1,2 +1,4 @@
 obj-$(CONFIG_FB_MXC_LDB) += ldb.o
+obj-$(CONFIG_FB_MXC_HDMI)                      += mxc_hdmi.o
+obj-$(CONFIG_FB_MXC_EDID)                      += mxc_edid.o
 obj-$(CONFIG_FB_MXC_SYNC_PANEL) += mxc_dispdrv.o mxc_lcdif.o mxc_ipuv3_fb.o
diff --git a/drivers/video/mxc/mxc_edid.c b/drivers/video/mxc/mxc_edid.c
new file mode 100644 (file)
index 0000000..88b5268
--- /dev/null
@@ -0,0 +1,762 @@
+/*
+ * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
+ */
+
+/*!
+ * @file mxc_edid.c
+ *
+ * @brief MXC EDID driver
+ *
+ * @ingroup Framebuffer
+ */
+
+/*!
+ * Include files
+ */
+#include <linux/i2c.h>
+#include <linux/fb.h>
+#include <video/mxc_edid.h>
+#include "../edid.h"
+
+#undef DEBUG  /* define this for verbose EDID parsing output */
+#ifdef DEBUG
+#define DPRINTK(fmt, args...) printk(fmt, ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+const struct fb_videomode mxc_cea_mode[64] = {
+       /* #1: 640x480p@59.94/60Hz 4:3 */
+       [1] = {
+               NULL, 60, 640, 480, 39722, 48, 16, 33, 10, 96, 2, 0,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+       },
+       /* #2: 720x480p@59.94/60Hz 4:3 */
+       [2] = {
+               NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+       },
+       /* #3: 720x480p@59.94/60Hz 16:9 */
+       [3] = {
+               NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+       },
+       /* #4: 1280x720p@59.94/60Hz 16:9 */
+       [4] = {
+               NULL, 60, 1280, 720, 13468, 220, 110, 20, 5, 40, 5,
+               FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
+       },
+       /* #5: 1920x1080i@59.94/60Hz 16:9 */
+       [5] = {
+               NULL, 60, 1920, 1080, 13763, 148, 88, 15, 2, 44, 5,
+               FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+               FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
+       },
+       /* #6: 720(1440)x480iH@59.94/60Hz 4:3 */
+       [6] = {
+               NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0,
+               FB_VMODE_INTERLACED | FB_VMODE_ASPECT_4_3, 0,
+       },
+       /* #7: 720(1440)x480iH@59.94/60Hz 16:9 */
+       [7] = {
+               NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0,
+               FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
+       },
+       /* #8: 720(1440)x240pH@59.94/60Hz 4:3 */
+       [8] = {
+               NULL, 60, 1440, 240, 37108, 114, 38, 15, 4, 124, 3, 0,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+       },
+       /* #9: 720(1440)x240pH@59.94/60Hz 16:9 */
+       [9] = {
+               NULL, 60, 1440, 240, 37108, 114, 38, 15, 4, 124, 3, 0,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+       },
+       /* #14: 1440x480p@59.94/60Hz 4:3 */
+       [14] = {
+               NULL, 60, 1440, 480, 18500, 120, 32, 30, 9, 124, 6, 0,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+       },
+       /* #15: 1440x480p@59.94/60Hz 16:9 */
+       [15] = {
+               NULL, 60, 1440, 480, 18500, 120, 32, 30, 9, 124, 6, 0,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+       },
+       /* #16: 1920x1080p@60Hz 16:9 */
+       [16] = {
+               NULL, 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5,
+               FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+       },
+       /* #17: 720x576pH@50Hz 4:3 */
+       [17] = {
+               NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+       },
+       /* #18: 720x576pH@50Hz 16:9 */
+       [18] = {
+               NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+       },
+       /* #19: 1280x720p@50Hz */
+       [19] = {
+               NULL, 50, 1280, 720, 13468, 220, 440, 20, 5, 40, 5,
+               FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+       },
+       /* #20: 1920x1080i@50Hz */
+       [20] = {
+               NULL, 50, 1920, 1080, 13480, 148, 528, 15, 5, 528, 5,
+               FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+               FB_VMODE_INTERLACED | FB_VMODE_ASPECT_16_9, 0,
+       },
+       /* #23: 720(1440)x288pH@50Hz 4:3 */
+       [23] = {
+               NULL, 50, 1440, 288, 37037, 138, 24, 19, 2, 126, 3, 0,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+       },
+       /* #24: 720(1440)x288pH@50Hz 16:9 */
+       [24] = {
+               NULL, 50, 1440, 288, 37037, 138, 24, 19, 2, 126, 3, 0,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+       },
+       /* #29: 720(1440)x576pH@50Hz 4:3 */
+       [29] = {
+               NULL, 50, 1440, 576, 18518, 136, 24, 39, 5, 128, 5, 0,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, 0,
+       },
+       /* #30: 720(1440)x576pH@50Hz 16:9 */
+       [30] = {
+               NULL, 50, 1440, 576, 18518, 136, 24, 39, 5, 128, 5, 0,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+       },
+       /* #31: 1920x1080p@50Hz */
+       [31] = {
+               NULL, 50, 1920, 1080, 6734, 148, 528, 36, 4, 44, 5,
+               FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+       },
+       /* #32: 1920x1080p@23.98/24Hz */
+       [32] = {
+               NULL, 24, 1920, 1080, 13468, 148, 638, 36, 4, 44, 5,
+               FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+       },
+       /* #33: 1920x1080p@25Hz */
+       [33] = {
+               NULL, 25, 1920, 1080, 13468, 148, 528, 36, 4, 44, 5,
+               FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+       },
+       /* #34: 1920x1080p@30Hz */
+       [34] = {
+               NULL, 30, 1920, 1080, 13468, 148, 88, 36, 4, 44, 5,
+               FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0,
+       },
+       /* #41: 1280x720p@100Hz 16:9 */
+       [41] = {
+               NULL, 100, 1280, 720, 6734, 220, 440, 20, 5, 40, 5,
+               FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
+       },
+       /* #47: 1280x720p@119.88/120Hz 16:9 */
+       [47] = {
+               NULL, 120, 1280, 720, 6734, 220, 110, 20, 5, 40, 5,
+               FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+               FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_16_9, 0
+       },
+};
+
+/*
+ * We have a special version of fb_mode_is_equal that ignores
+ * pixclock, since for many CEA modes, 2 frequencies are supported
+ * e.g. 640x480 @ 60Hz or 59.94Hz
+ */
+int mxc_edid_fb_mode_is_equal(bool use_aspect,
+                       const struct fb_videomode *mode1,
+                       const struct fb_videomode *mode2)
+{
+       u32 mask;
+
+       if (use_aspect)
+               mask = ~0;
+       else
+               mask = ~FB_VMODE_ASPECT_MASK;
+
+       return (mode1->xres         == mode2->xres &&
+               mode1->yres         == mode2->yres &&
+               mode1->hsync_len    == mode2->hsync_len &&
+               mode1->vsync_len    == mode2->vsync_len &&
+               mode1->left_margin  == mode2->left_margin &&
+               mode1->right_margin == mode2->right_margin &&
+               mode1->upper_margin == mode2->upper_margin &&
+               mode1->lower_margin == mode2->lower_margin &&
+               mode1->sync         == mode2->sync &&
+               /* refresh check, 59.94Hz and 60Hz have the same parameter
+                * in struct of mxc_cea_mode */
+               abs(mode1->refresh - mode2->refresh) <= 1 &&
+               (mode1->vmode & mask) == (mode2->vmode & mask));
+}
+
+static void get_detailed_timing(unsigned char *block,
+                               struct fb_videomode *mode)
+{
+       mode->xres = H_ACTIVE;
+       mode->yres = V_ACTIVE;
+       mode->pixclock = PIXEL_CLOCK;
+       mode->pixclock /= 1000;
+       mode->pixclock = KHZ2PICOS(mode->pixclock);
+       mode->right_margin = H_SYNC_OFFSET;
+       mode->left_margin = (H_ACTIVE + H_BLANKING) -
+               (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
+       mode->upper_margin = V_BLANKING - V_SYNC_OFFSET -
+               V_SYNC_WIDTH;
+       mode->lower_margin = V_SYNC_OFFSET;
+       mode->hsync_len = H_SYNC_WIDTH;
+       mode->vsync_len = V_SYNC_WIDTH;
+       if (HSYNC_POSITIVE)
+               mode->sync |= FB_SYNC_HOR_HIGH_ACT;
+       if (VSYNC_POSITIVE)
+               mode->sync |= FB_SYNC_VERT_HIGH_ACT;
+       mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) *
+                                    (V_ACTIVE + V_BLANKING));
+       if (INTERLACED) {
+               mode->yres *= 2;
+               mode->upper_margin *= 2;
+               mode->lower_margin *= 2;
+               mode->vsync_len *= 2;
+               mode->vmode |= FB_VMODE_INTERLACED;
+       }
+       mode->flag = FB_MODE_IS_DETAILED;
+
+       if ((H_SIZE / 16) == (V_SIZE / 9))
+               mode->vmode |= FB_VMODE_ASPECT_16_9;
+       else if ((H_SIZE / 4) == (V_SIZE / 3))
+               mode->vmode |= FB_VMODE_ASPECT_4_3;
+       else if ((mode->xres / 16) == (mode->yres / 9))
+               mode->vmode |= FB_VMODE_ASPECT_16_9;
+       else if ((mode->xres / 4) == (mode->yres / 3))
+               mode->vmode |= FB_VMODE_ASPECT_4_3;
+
+       if (mode->vmode & FB_VMODE_ASPECT_16_9)
+               DPRINTK("Aspect ratio: 16:9\n");
+       if (mode->vmode & FB_VMODE_ASPECT_4_3)
+               DPRINTK("Aspect ratio: 4:3\n");
+       DPRINTK("      %d MHz ",  PIXEL_CLOCK/1000000);
+       DPRINTK("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET,
+              H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING);
+       DPRINTK("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET,
+              V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING);
+       DPRINTK("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-",
+              (VSYNC_POSITIVE) ? "+" : "-");
+}
+
+int mxc_edid_parse_ext_blk(unsigned char *edid,
+               struct mxc_edid_cfg *cfg,
+               struct fb_monspecs *specs)
+{
+       char detail_timing_desc_offset;
+       struct fb_videomode *mode, *m;
+       unsigned char index = 0x0;
+       unsigned char *block;
+       int i, num = 0, revision;
+
+       if (edid[index++] != 0x2) /* only support cea ext block now */
+               return -1;
+       revision = edid[index++];
+       DPRINTK("cea extent revision %d\n", revision);
+       mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL);
+       if (mode == NULL)
+               return -1;
+
+       detail_timing_desc_offset = edid[index++];
+
+       if (revision >= 2) {
+               cfg->cea_underscan = (edid[index] >> 7) & 0x1;
+               cfg->cea_basicaudio = (edid[index] >> 6) & 0x1;
+               cfg->cea_ycbcr444 = (edid[index] >> 5) & 0x1;
+               cfg->cea_ycbcr422 = (edid[index] >> 4) & 0x1;
+
+               DPRINTK("CEA underscan %d\n", cfg->cea_underscan);
+               DPRINTK("CEA basicaudio %d\n", cfg->cea_basicaudio);
+               DPRINTK("CEA ycbcr444 %d\n", cfg->cea_ycbcr444);
+               DPRINTK("CEA ycbcr422 %d\n", cfg->cea_ycbcr422);
+       }
+
+       if (revision >= 3) {
+               /* short desc */
+               DPRINTK("CEA Short desc timmings\n");
+               index++;
+               while (index < detail_timing_desc_offset) {
+                       unsigned char tagcode, blklen;
+
+                       tagcode = (edid[index] >> 5) & 0x7;
+                       blklen = (edid[index]) & 0x1f;
+
+                       DPRINTK("Tagcode %x Len %d\n", tagcode, blklen);
+
+                       switch (tagcode) {
+                       case 0x2: /*Video data block*/
+                               {
+                                       int cea_idx;
+                                       i = 0;
+                                       while (i < blklen) {
+                                               index++;
+                                               cea_idx = edid[index] & 0x7f;
+                                               if (cea_idx < ARRAY_SIZE(mxc_cea_mode) &&
+                                                               (mxc_cea_mode[cea_idx].xres)) {
+                                                       DPRINTK("Support CEA Format #%d\n", cea_idx);
+                                                       mode[num] = mxc_cea_mode[cea_idx];
+                                                       mode[num].flag |= FB_MODE_IS_STANDARD;
+                                                       num++;
+                                               }
+                                               i++;
+                                       }
+                                       break;
+                               }
+                       case 0x3: /*Vendor specific data*/
+                               {
+                                       unsigned char IEEE_reg_iden[3];
+                                       unsigned char deep_color;
+                                       unsigned char latency_present;
+                                       unsigned char I_latency_present;
+                                       unsigned char hdmi_video_present;
+                                       unsigned char hdmi_3d_present;
+                                       unsigned char hdmi_3d_multi_present;
+                                       unsigned char hdmi_vic_len;
+                                       unsigned char hdmi_3d_len;
+                                       unsigned char index_inc = 0;
+                                       unsigned char vsd_end;
+
+                                       vsd_end = index + blklen;
+
+                                       IEEE_reg_iden[0] = edid[index+1];
+                                       IEEE_reg_iden[1] = edid[index+2];
+                                       IEEE_reg_iden[2] = edid[index+3];
+                                       cfg->physical_address[0] = (edid[index+4] & 0xf0) >> 4;
+                                       cfg->physical_address[1] = (edid[index+4] & 0x0f);
+                                       cfg->physical_address[2] = (edid[index+5] & 0xf0) >> 4;
+                                       cfg->physical_address[3] = (edid[index+5] & 0x0f);
+
+                                       if ((IEEE_reg_iden[0] == 0x03) &&
+                                                       (IEEE_reg_iden[1] == 0x0c) &&
+                                                       (IEEE_reg_iden[2] == 0x00))
+                                               cfg->hdmi_cap = 1;
+
+                                       if (blklen > 5) {
+                                               deep_color = edid[index+6];
+                                               if (deep_color & 0x80)
+                                                       cfg->vsd_support_ai = true;
+                                               if (deep_color & 0x40)
+                                                       cfg->vsd_dc_48bit = true;
+                                               if (deep_color & 0x20)
+                                                       cfg->vsd_dc_36bit = true;
+                                               if (deep_color & 0x10)
+                                                       cfg->vsd_dc_30bit = true;
+                                               if (deep_color & 0x08)
+                                                       cfg->vsd_dc_y444 = true;
+                                               if (deep_color & 0x01)
+                                                       cfg->vsd_dvi_dual = true;
+                                       }
+
+                                       DPRINTK("VSD hdmi capability %d\n", cfg->hdmi_cap);
+                                       DPRINTK("VSD support ai %d\n", cfg->vsd_support_ai);
+                                       DPRINTK("VSD support deep color 48bit %d\n", cfg->vsd_dc_48bit);
+                                       DPRINTK("VSD support deep color 36bit %d\n", cfg->vsd_dc_36bit);
+                                       DPRINTK("VSD support deep color 30bit %d\n", cfg->vsd_dc_30bit);
+                                       DPRINTK("VSD support deep color y444 %d\n", cfg->vsd_dc_y444);
+                                       DPRINTK("VSD support dvi dual %d\n", cfg->vsd_dvi_dual);
+
+                                       if (blklen > 6)
+                                               cfg->vsd_max_tmdsclk_rate = edid[index+7] * 5;
+                                       DPRINTK("VSD MAX TMDS CLOCK RATE %d\n", cfg->vsd_max_tmdsclk_rate);
+
+                                       if (blklen > 7) {
+                                               latency_present = edid[index+8] >> 7;
+                                               I_latency_present =  (edid[index+8] & 0x40) >> 6;
+                                               hdmi_video_present = (edid[index+8] & 0x20) >> 5;
+                                               cfg->vsd_cnc3 = (edid[index+8] & 0x8) >> 3;
+                                               cfg->vsd_cnc2 = (edid[index+8] & 0x4) >> 2;
+                                               cfg->vsd_cnc1 = (edid[index+8] & 0x2) >> 1;
+                                               cfg->vsd_cnc0 = edid[index+8] & 0x1;
+
+                                               DPRINTK("VSD cnc0 %d\n", cfg->vsd_cnc0);
+                                               DPRINTK("VSD cnc1 %d\n", cfg->vsd_cnc1);
+                                               DPRINTK("VSD cnc2 %d\n", cfg->vsd_cnc2);
+                                               DPRINTK("VSD cnc3 %d\n", cfg->vsd_cnc3);
+                                               DPRINTK("latency_present %d\n", latency_present);
+                                               DPRINTK("I_latency_present %d\n", I_latency_present);
+                                               DPRINTK("hdmi_video_present %d\n", hdmi_video_present);
+
+                                       } else {
+                                               index += blklen;
+                                               break;
+                                       }
+
+                                       index += 9;
+
+                                       /*latency present */
+                                       if (latency_present) {
+                                               cfg->vsd_video_latency = edid[index++];
+                                               cfg->vsd_audio_latency = edid[index++];
+
+                                               if (I_latency_present) {
+                                                       cfg->vsd_I_video_latency = edid[index++];
+                                                       cfg->vsd_I_audio_latency = edid[index++];
+                                               } else {
+                                                       cfg->vsd_I_video_latency = cfg->vsd_video_latency;
+                                                       cfg->vsd_I_audio_latency = cfg->vsd_audio_latency;
+                                               }
+
+                                               DPRINTK("VSD latency video_latency  %d\n", cfg->vsd_video_latency);
+                                               DPRINTK("VSD latency audio_latency  %d\n", cfg->vsd_audio_latency);
+                                               DPRINTK("VSD latency I_video_latency  %d\n", cfg->vsd_I_video_latency);
+                                               DPRINTK("VSD latency I_audio_latency  %d\n", cfg->vsd_I_audio_latency);
+                                       }
+
+                                       if (hdmi_video_present) {
+                                               hdmi_3d_present = edid[index] >> 7;
+                                               hdmi_3d_multi_present = (edid[index] & 0x60) >> 5;
+                                               index++;
+                                               hdmi_vic_len = (edid[index] & 0xe0) >> 5;
+                                               hdmi_3d_len = edid[index] & 0x1f;
+                                               index++;
+
+                                               DPRINTK("hdmi_3d_present %d\n", hdmi_3d_present);
+                                               DPRINTK("hdmi_3d_multi_present %d\n", hdmi_3d_multi_present);
+                                               DPRINTK("hdmi_vic_len %d\n", hdmi_vic_len);
+                                               DPRINTK("hdmi_3d_len %d\n", hdmi_3d_len);
+
+                                               if (hdmi_vic_len > 0) {
+                                                       for (i = 0; i < hdmi_vic_len; i++) {
+                                                               cfg->hdmi_vic[i] = edid[index++];
+                                                               DPRINTK("HDMI_vic=%d\n", cfg->hdmi_vic[i]);
+                                                       }
+                                               }
+
+                                               if (hdmi_3d_len > 0) {
+                                                       if (hdmi_3d_present) {
+                                                               if (hdmi_3d_multi_present == 0x1) {
+                                                                       cfg->hdmi_3d_struct_all = (edid[index] << 8) | edid[index+1];
+                                                                       index_inc = 2;
+                                                               } else if (hdmi_3d_multi_present == 0x2) {
+                                                                       cfg->hdmi_3d_struct_all = (edid[index] << 8) | edid[index+1];
+                                                                       cfg->hdmi_3d_mask_all = (edid[index+2] << 8) | edid[index+3];
+                                                                       index_inc = 4;
+                                                               } else
+                                                                       index_inc = 0;
+                                                       }
+
+                                                       DPRINTK("HDMI 3d struct all =0x%x\n", cfg->hdmi_3d_struct_all);
+                                                       DPRINTK("HDMI 3d mask all =0x%x\n", cfg->hdmi_3d_mask_all);
+
+                                                       /* Read 2D vic 3D_struct */
+                                                       if ((hdmi_3d_len - index_inc) > 0) {
+                                                               DPRINTK("Support 3D video format\n");
+                                                               i = 0;
+                                                               while ((hdmi_3d_len - index_inc) > 0) {
+
+                                                                       cfg->hdmi_3d_format[i].vic_order_2d = edid[index+index_inc] >> 4;
+                                                                       cfg->hdmi_3d_format[i].struct_3d = edid[index+index_inc] & 0x0f;
+                                                                       index_inc++;
+
+                                                                       if (cfg->hdmi_3d_format[i].struct_3d ==  8) {
+                                                                               cfg->hdmi_3d_format[i].detail_3d = edid[index+index_inc] >> 4;
+                                                                               index_inc++;
+                                                                       } else if (cfg->hdmi_3d_format[i].struct_3d > 8) {
+                                                                               cfg->hdmi_3d_format[i].detail_3d = 0;
+                                                                               index_inc++;
+                                                                       }
+
+                                                                       DPRINTK("vic_order_2d=%d, 3d_struct=%d, 3d_detail=0x%x\n",
+                                                                                       cfg->hdmi_3d_format[i].vic_order_2d,
+                                                                                       cfg->hdmi_3d_format[i].struct_3d,
+                                                                                       cfg->hdmi_3d_format[i].detail_3d);
+                                                                       i++;
+                                                               }
+                                                       }
+                                                       index += index_inc;
+                                               }
+                                       }
+
+                                       index = vsd_end;
+
+                                       break;
+                               }
+                       case 0x1: /*Audio data block*/
+                               {
+                                       u8 audio_format, max_ch, byte1, byte2, byte3;
+
+                                       i = 0;
+                                       cfg->max_channels = 0;
+                                       cfg->sample_rates = 0;
+                                       cfg->sample_sizes = 0;
+
+                                       while (i < blklen) {
+                                               byte1 = edid[index + 1];
+                                               byte2 = edid[index + 2];
+                                               byte3 = edid[index + 3];
+                                               index += 3;
+                                               i += 3;
+
+                                               audio_format = byte1 >> 3;
+                                               max_ch = (byte1 & 0x07) + 1;
+
+                                               DPRINTK("Audio Format Descriptor : %2d\n", audio_format);
+                                               DPRINTK("Max Number of Channels  : %2d\n", max_ch);
+                                               DPRINTK("Sample Rates            : %02x\n", byte2);
+
+                                               /* ALSA can't specify specific compressed
+                                                * formats, so only care about PCM for now. */
+                                               if (audio_format == AUDIO_CODING_TYPE_LPCM) {
+                                                       if (max_ch > cfg->max_channels)
+                                                               cfg->max_channels = max_ch;
+
+                                                       cfg->sample_rates |= byte2;
+                                                       cfg->sample_sizes |= byte3 & 0x7;
+                                                       DPRINTK("Sample Sizes            : %02x\n",
+                                                               byte3 & 0x7);
+                                               }
+                                       }
+                                       break;
+                               }
+                       case 0x4: /*Speaker allocation block*/
+                               {
+                                       i = 0;
+                                       while (i < blklen) {
+                                               cfg->speaker_alloc = edid[index + 1];
+                                               index += 3;
+                                               i += 3;
+                                               DPRINTK("Speaker Alloc           : %02x\n", cfg->speaker_alloc);
+                                       }
+                                       break;
+                               }
+                       case 0x7: /*User extended block*/
+                       default:
+                               /* skip */
+                               DPRINTK("Not handle block, tagcode = 0x%x\n", tagcode);
+                               index += blklen;
+                               break;
+                       }
+
+                       index++;
+               }
+       }
+
+       /* long desc */
+       DPRINTK("CEA long desc timmings\n");
+       index = detail_timing_desc_offset;
+       block = edid + index;
+       while (index < (EDID_LENGTH - DETAILED_TIMING_DESCRIPTION_SIZE)) {
+               if (!(block[0] == 0x00 && block[1] == 0x00)) {
+                       get_detailed_timing(block, &mode[num]);
+                       num++;
+               }
+               block += DETAILED_TIMING_DESCRIPTION_SIZE;
+               index += DETAILED_TIMING_DESCRIPTION_SIZE;
+       }
+
+       if (!num) {
+               kfree(mode);
+               return 0;
+       }
+
+       m = kmalloc((num + specs->modedb_len) *
+                       sizeof(struct fb_videomode), GFP_KERNEL);
+       if (!m)
+               return 0;
+
+       if (specs->modedb_len) {
+               memmove(m, specs->modedb,
+                       specs->modedb_len * sizeof(struct fb_videomode));
+               kfree(specs->modedb);
+       }
+       memmove(m+specs->modedb_len, mode,
+               num * sizeof(struct fb_videomode));
+       kfree(mode);
+
+       specs->modedb_len += num;
+       specs->modedb = m;
+
+       return 0;
+}
+EXPORT_SYMBOL(mxc_edid_parse_ext_blk);
+
+static int mxc_edid_readblk(struct i2c_adapter *adp,
+               unsigned short addr, unsigned char *edid)
+{
+       int ret = 0, extblknum = 0;
+       unsigned char regaddr = 0x0;
+       struct i2c_msg msg[2] = {
+               {
+               .addr   = addr,
+               .flags  = 0,
+               .len    = 1,
+               .buf    = &regaddr,
+               }, {
+               .addr   = addr,
+               .flags  = I2C_M_RD,
+               .len    = EDID_LENGTH,
+               .buf    = edid,
+               },
+       };
+
+       ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
+       if (ret != ARRAY_SIZE(msg)) {
+               DPRINTK("unable to read EDID block\n");
+               return -EIO;
+       }
+
+       if (edid[1] == 0x00)
+               return -ENOENT;
+
+       extblknum = edid[0x7E];
+
+       if (extblknum) {
+               regaddr = 128;
+               msg[1].buf = edid + EDID_LENGTH;
+
+               ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
+               if (ret != ARRAY_SIZE(msg)) {
+                       DPRINTK("unable to read EDID ext block\n");
+                       return -EIO;
+               }
+       }
+
+       return extblknum;
+}
+
+static int mxc_edid_readsegblk(struct i2c_adapter *adp, unsigned short addr,
+                       unsigned char *edid, int seg_num)
+{
+       int ret = 0;
+       unsigned char segment = 0x1, regaddr = 0;
+       struct i2c_msg msg[3] = {
+               {
+               .addr   = 0x30,
+               .flags  = 0,
+               .len    = 1,
+               .buf    = &segment,
+               }, {
+               .addr   = addr,
+               .flags  = 0,
+               .len    = 1,
+               .buf    = &regaddr,
+               }, {
+               .addr   = addr,
+               .flags  = I2C_M_RD,
+               .len    = EDID_LENGTH,
+               .buf    = edid,
+               },
+       };
+
+       ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
+       if (ret != ARRAY_SIZE(msg)) {
+               DPRINTK("unable to read EDID block\n");
+               return -EIO;
+       }
+
+       if (seg_num == 2) {
+               regaddr = 128;
+               msg[2].buf = edid + EDID_LENGTH;
+
+               ret = i2c_transfer(adp, msg, ARRAY_SIZE(msg));
+               if (ret != ARRAY_SIZE(msg)) {
+                       DPRINTK("unable to read EDID block\n");
+                       return -EIO;
+               }
+       }
+
+       return ret;
+}
+
+int mxc_edid_var_to_vic(struct fb_var_screeninfo *var)
+{
+       int i;
+       struct fb_videomode m;
+
+       for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
+               fb_var_to_videomode(&m, var);
+               if (mxc_edid_fb_mode_is_equal(false, &m, &mxc_cea_mode[i]))
+                       break;
+       }
+
+       if (i == ARRAY_SIZE(mxc_cea_mode))
+               return 0;
+
+       return i;
+}
+EXPORT_SYMBOL(mxc_edid_var_to_vic);
+
+int mxc_edid_mode_to_vic(const struct fb_videomode *mode)
+{
+       int i;
+       bool use_aspect = (mode->vmode & FB_VMODE_ASPECT_MASK);
+
+       for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
+               if (mxc_edid_fb_mode_is_equal(use_aspect, mode, &mxc_cea_mode[i]))
+                       break;
+       }
+
+       if (i == ARRAY_SIZE(mxc_cea_mode))
+               return 0;
+
+       return i;
+}
+EXPORT_SYMBOL(mxc_edid_mode_to_vic);
+
+/* make sure edid has 512 bytes*/
+int mxc_edid_read(struct i2c_adapter *adp, unsigned short addr,
+       unsigned char *edid, struct mxc_edid_cfg *cfg, struct fb_info *fbi)
+{
+       int ret = 0, extblknum;
+       if (!adp || !edid || !cfg || !fbi)
+               return -EINVAL;
+
+       memset(edid, 0, EDID_LENGTH*4);
+       memset(cfg, 0, sizeof(struct mxc_edid_cfg));
+
+       extblknum = mxc_edid_readblk(adp, addr, edid);
+       if (extblknum < 0)
+               return extblknum;
+
+       /* edid first block parsing */
+       memset(&fbi->monspecs, 0, sizeof(fbi->monspecs));
+       fb_edid_to_monspecs(edid, &fbi->monspecs);
+
+       if (extblknum) {
+               int i;
+
+               /* need read segment block? */
+               if (extblknum > 1) {
+                       ret = mxc_edid_readsegblk(adp, addr,
+                               edid + EDID_LENGTH*2, extblknum - 1);
+                       if (ret < 0)
+                               return ret;
+               }
+
+               for (i = 1; i <= extblknum; i++)
+                       /* edid ext block parsing */
+                       mxc_edid_parse_ext_blk(edid + i*EDID_LENGTH,
+                                       cfg, &fbi->monspecs);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(mxc_edid_read);
+
diff --git a/drivers/video/mxc/mxc_hdmi.c b/drivers/video/mxc/mxc_hdmi.c
new file mode 100644 (file)
index 0000000..6c0d422
--- /dev/null
@@ -0,0 +1,2971 @@
+/*
+ * 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.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+/*
+ * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
+ * for SLISHDMI13T and SLIPHDMIT IP cores
+ *
+ * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/uaccess.h>
+#include <linux/cpufreq.h>
+#include <linux/firmware.h>
+#include <linux/kthread.h>
+#include <linux/regulator/driver.h>
+#include <linux/fsl_devices.h>
+#include <linux/ipu.h>
+#include <linux/regmap.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/of_device.h>
+
+#include <linux/console.h>
+#include <linux/types.h>
+
+#include "../edid.h"
+#include <video/mxc_edid.h>
+#include <video/mxc_hdmi.h>
+#include "mxc_dispdrv.h"
+
+#include <linux/mfd/mxc-hdmi-core.h>
+
+#define DISPDRV_HDMI   "hdmi"
+#define HDMI_EDID_LEN          512
+
+/* status codes for reading edid */
+#define HDMI_EDID_SUCCESS      0
+#define HDMI_EDID_FAIL         -1
+#define HDMI_EDID_SAME         -2
+#define HDMI_EDID_NO_MODES     -3
+
+#define NUM_CEA_VIDEO_MODES    64
+#define DEFAULT_VIDEO_MODE     16 /* 1080P */
+
+#define RGB                    0
+#define YCBCR444               1
+#define YCBCR422_16BITS                2
+#define YCBCR422_8BITS         3
+#define XVYCC444            4
+
+/*
+ * We follow a flowchart which is in the "Synopsys DesignWare Courses
+ * HDMI Transmitter Controller User Guide, 1.30a", section 3.1
+ * (dwc_hdmi_tx_user.pdf)
+ *
+ * Below are notes that say "HDMI Initialization Step X"
+ * These correspond to the flowchart.
+ */
+
+/*
+ * We are required to configure VGA mode before reading edid
+ * in HDMI Initialization Step B
+ */
+static const struct fb_videomode vga_mode = {
+       /* 640x480 @ 60 Hz, 31.5 kHz hsync */
+       NULL, 60, 640, 480, 39721, 48, 16, 33, 10, 96, 2, 0,
+       FB_VMODE_NONINTERLACED | FB_VMODE_ASPECT_4_3, FB_MODE_IS_VESA,
+};
+
+static const struct fb_videomode xga_mode = {
+       /* 13 1024x768-60 VESA */
+       NULL, 60, 1024, 768, 15384, 160, 24, 29, 3, 136, 6,
+       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA
+};
+
+static const struct fb_videomode sxga_mode = {
+       /* 20 1280x1024-60 VESA */
+       NULL, 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
+       FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+       FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA
+};
+
+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 hdmi_colorimetry {
+       eITU601,
+       eITU709,
+};
+
+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;
+       unsigned int rgb_out_enable;
+       struct hdmi_vmode video_mode;
+};
+
+struct hdmi_phy_reg_config {
+       /* HDMI PHY register config for pass HCT */
+       u16 reg_vlev;
+       u16 reg_cksymtx;
+};
+
+struct mxc_hdmi {
+       struct platform_device *pdev;
+       struct platform_device *core_pdev;
+       struct mxc_dispdrv_handle *disp_mxc_hdmi;
+       struct fb_info *fbi;
+       struct clk *hdmi_isfr_clk;
+       struct clk *hdmi_iahb_clk;
+       struct delayed_work hotplug_work;
+       struct delayed_work hdcp_hdp_work;
+
+       struct notifier_block nb;
+
+       struct hdmi_data_info hdmi_data;
+       int vic;
+       struct mxc_edid_cfg edid_cfg;
+       u8 edid[HDMI_EDID_LEN];
+       bool fb_reg;
+       bool cable_plugin;
+       u8  blank;
+       bool dft_mode_set;
+       char *dft_mode_str;
+       int default_bpp;
+       u8 latest_intr_stat;
+       bool irq_enabled;
+       spinlock_t irq_lock;
+       bool phy_enabled;
+       struct fb_videomode previous_mode;
+       struct fb_videomode previous_non_vga_mode;
+       bool requesting_vga_for_initialization;
+
+       int *gpr_base;
+       int *gpr_hdmi_base;
+       int *gpr_sdma_base;
+       int cpu_type;
+       int cpu_version;
+       struct hdmi_phy_reg_config phy_config;
+
+       struct pinctrl *pinctrl;
+       struct pinctrl_state *pins_hdcp;
+       struct pinctrl_state *pins_cec;
+};
+
+enum imx_hdmim_type {
+       IMX6DL_HDMI,
+       IMX6Q_HDMI,
+};
+
+static int hdmi_major;
+static struct class *hdmi_class;
+
+
+struct i2c_client *hdmi_i2c;
+struct mxc_hdmi *g_hdmi;
+
+static bool hdmi_inited;
+
+extern const struct fb_videomode mxc_cea_mode[64];
+extern void mxc_hdmi_cec_handle(u16 cec_stat);
+
+static void mxc_hdmi_setup(struct mxc_hdmi *hdmi, unsigned long event);
+
+static struct platform_device_id imx_hdmi_devtype[] = {
+       {
+               .name = "hdmi-imx6DL",
+               .driver_data = IMX6DL_HDMI,
+       }, {
+               .name = "hdmi-imx6Q",
+               .driver_data = IMX6Q_HDMI,
+       }, {
+               /* sentinel */
+       }
+};
+MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype);
+
+static const struct of_device_id imx_hdmi_dt_ids[] = {
+       { .compatible = "fsl,imx6dl-hdmi-video", .data = &imx_hdmi_devtype[IMX6DL_HDMI], },
+       { .compatible = "fsl,imx6q-hdmi-video", .data = &imx_hdmi_devtype[IMX6Q_HDMI], },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
+
+static inline int cpu_is_imx6dl(struct mxc_hdmi *hdmi)
+{
+       return hdmi->cpu_type == IMX6DL_HDMI;
+}
+#ifdef DEBUG
+static void dump_fb_videomode(struct fb_videomode *m)
+{
+       pr_debug("fb_videomode = %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
+               m->refresh, m->xres, m->yres, m->pixclock, m->left_margin,
+               m->right_margin, m->upper_margin, m->lower_margin,
+               m->hsync_len, m->vsync_len, m->sync, m->vmode, m->flag);
+}
+#else
+static void dump_fb_videomode(struct fb_videomode *m)
+{}
+#endif
+
+static int hdcp_init;
+static int __init early_init_hdcp(char *p)
+{
+       hdcp_init = 1;
+       return 0;
+}
+early_param("hdcp", early_init_hdcp);
+
+static ssize_t mxc_hdmi_show_name(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
+
+       strcpy(buf, hdmi->fbi->fix.id);
+       sprintf(buf+strlen(buf), "\n");
+
+       return strlen(buf);
+}
+
+static DEVICE_ATTR(fb_name, S_IRUGO, mxc_hdmi_show_name, NULL);
+
+static ssize_t mxc_hdmi_show_state(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
+
+       if (hdmi->cable_plugin == false)
+               strcpy(buf, "plugout\n");
+       else
+               strcpy(buf, "plugin\n");
+
+       return strlen(buf);
+}
+
+static DEVICE_ATTR(cable_state, S_IRUGO, mxc_hdmi_show_state, NULL);
+
+static ssize_t mxc_hdmi_show_edid(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
+       int i, j, len = 0;
+
+       for (j = 0; j < HDMI_EDID_LEN/16; j++) {
+               for (i = 0; i < 16; i++)
+                       len += sprintf(buf+len, "0x%02X ",
+                                       hdmi->edid[j*16 + i]);
+               len += sprintf(buf+len, "\n");
+       }
+
+       return len;
+}
+
+static DEVICE_ATTR(edid, S_IRUGO, mxc_hdmi_show_edid, NULL);
+
+static ssize_t mxc_hdmi_show_rgb_out_enable(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
+
+       if (hdmi->hdmi_data.rgb_out_enable == true)
+               strcpy(buf, "RGB out\n");
+       else
+               strcpy(buf, "YCbCr out\n");
+
+       return strlen(buf);
+}
+
+static ssize_t mxc_hdmi_store_rgb_out_enable(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
+       unsigned long value;
+       int ret;
+
+       ret = strict_strtoul(buf, 10, &value);
+       if (ret)
+               return ret;
+
+       hdmi->hdmi_data.rgb_out_enable = value;
+
+       /* Reconfig HDMI for output color space change */
+       mxc_hdmi_setup(hdmi, 0);
+
+       return count;
+}
+
+static DEVICE_ATTR(rgb_out_enable, S_IRUGO | S_IWUSR,
+                               mxc_hdmi_show_rgb_out_enable,
+                               mxc_hdmi_store_rgb_out_enable);
+
+static ssize_t mxc_hdmi_show_hdcp_enable(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
+
+       if (hdmi->hdmi_data.hdcp_enable == false)
+               strcpy(buf, "hdcp disable\n");
+       else
+               strcpy(buf, "hdcp enable\n");
+
+       return strlen(buf);
+
+}
+
+static ssize_t mxc_hdmi_store_hdcp_enable(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct mxc_hdmi *hdmi = dev_get_drvdata(dev);
+       char event_string[32];
+       char *envp[] = { event_string, NULL };
+       unsigned long value;
+       int ret;
+
+       ret = strict_strtoul(buf, 10, &value);
+       if (ret)
+               return ret;
+
+       hdmi->hdmi_data.hdcp_enable = value;
+
+       /* Reconfig HDMI for HDCP */
+       mxc_hdmi_setup(hdmi, 0);
+
+       if (hdmi->hdmi_data.hdcp_enable == false) {
+               sprintf(event_string, "EVENT=hdcpdisable");
+               kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
+       } else {
+               sprintf(event_string, "EVENT=hdcpenable");
+               kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
+       }
+
+       return count;
+
+}
+
+static DEVICE_ATTR(hdcp_enable, S_IRUGO | S_IWUSR,
+                       mxc_hdmi_show_hdcp_enable, mxc_hdmi_store_hdcp_enable);
+
+/*!
+ * 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 mxc_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(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(val, HDMI_TX_INSTUFFING);
+       hdmi_writeb(0x0, HDMI_TX_GYDATA0);
+       hdmi_writeb(0x0, HDMI_TX_GYDATA1);
+       hdmi_writeb(0x0, HDMI_TX_RCRDATA0);
+       hdmi_writeb(0x0, HDMI_TX_RCRDATA1);
+       hdmi_writeb(0x0, HDMI_TX_BCBDATA0);
+       hdmi_writeb(0x0, HDMI_TX_BCBDATA1);
+}
+
+static int isColorSpaceConversion(struct mxc_hdmi *hdmi)
+{
+       return (hdmi->hdmi_data.enc_in_format !=
+               hdmi->hdmi_data.enc_out_format);
+}
+
+static int isColorSpaceDecimation(struct mxc_hdmi *hdmi)
+{
+       return ((hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) &&
+               (hdmi->hdmi_data.enc_in_format == RGB ||
+               hdmi->hdmi_data.enc_in_format == YCBCR444));
+}
+
+static int isColorSpaceInterpolation(struct mxc_hdmi *hdmi)
+{
+       return ((hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) &&
+               (hdmi->hdmi_data.enc_out_format == RGB
+               || hdmi->hdmi_data.enc_out_format == YCBCR444));
+}
+
+/*!
+ * update the color space conversion coefficients.
+ */
+static void update_csc_coeffs(struct mxc_hdmi *hdmi)
+{
+       unsigned short csc_coeff[3][4];
+       unsigned int csc_scale = 1;
+       u8 val;
+       bool coeff_selected = false;
+
+       if (isColorSpaceConversion(hdmi)) { /* csc needed */
+               if (hdmi->hdmi_data.enc_out_format == RGB) {
+                       if (hdmi->hdmi_data.colorimetry == eITU601) {
+                               csc_coeff[0][0] = 0x2000;
+                               csc_coeff[0][1] = 0x6926;
+                               csc_coeff[0][2] = 0x74fd;
+                               csc_coeff[0][3] = 0x010e;
+
+                               csc_coeff[1][0] = 0x2000;
+                               csc_coeff[1][1] = 0x2cdd;
+                               csc_coeff[1][2] = 0x0000;
+                               csc_coeff[1][3] = 0x7e9a;
+
+                               csc_coeff[2][0] = 0x2000;
+                               csc_coeff[2][1] = 0x0000;
+                               csc_coeff[2][2] = 0x38b4;
+                               csc_coeff[2][3] = 0x7e3b;
+
+                               csc_scale = 1;
+                               coeff_selected = true;
+                       } else if (hdmi->hdmi_data.colorimetry == eITU709) {
+                               csc_coeff[0][0] = 0x2000;
+                               csc_coeff[0][1] = 0x7106;
+                               csc_coeff[0][2] = 0x7a02;
+                               csc_coeff[0][3] = 0x00a7;
+
+                               csc_coeff[1][0] = 0x2000;
+                               csc_coeff[1][1] = 0x3264;
+                               csc_coeff[1][2] = 0x0000;
+                               csc_coeff[1][3] = 0x7e6d;
+
+                               csc_coeff[2][0] = 0x2000;
+                               csc_coeff[2][1] = 0x0000;
+                               csc_coeff[2][2] = 0x3b61;
+                               csc_coeff[2][3] = 0x7e25;
+
+                               csc_scale = 1;
+                               coeff_selected = true;
+                       }
+               } else if (hdmi->hdmi_data.enc_in_format == RGB) {
+                       if (hdmi->hdmi_data.colorimetry == eITU601) {
+                               csc_coeff[0][0] = 0x2591;
+                               csc_coeff[0][1] = 0x1322;
+                               csc_coeff[0][2] = 0x074b;
+                               csc_coeff[0][3] = 0x0000;
+
+                               csc_coeff[1][0] = 0x6535;
+                               csc_coeff[1][1] = 0x2000;
+                               csc_coeff[1][2] = 0x7acc;
+                               csc_coeff[1][3] = 0x0200;
+
+                               csc_coeff[2][0] = 0x6acd;
+                               csc_coeff[2][1] = 0x7534;
+                               csc_coeff[2][2] = 0x2000;
+                               csc_coeff[2][3] = 0x0200;
+
+                               csc_scale = 0;
+                               coeff_selected = true;
+                       } else if (hdmi->hdmi_data.colorimetry == eITU709) {
+                               csc_coeff[0][0] = 0x2dc5;
+                               csc_coeff[0][1] = 0x0d9b;
+                               csc_coeff[0][2] = 0x049e;
+                               csc_coeff[0][3] = 0x0000;
+
+                               csc_coeff[1][0] = 0x62f0;
+                               csc_coeff[1][1] = 0x2000;
+                               csc_coeff[1][2] = 0x7d11;
+                               csc_coeff[1][3] = 0x0200;
+
+                               csc_coeff[2][0] = 0x6756;
+                               csc_coeff[2][1] = 0x78ab;
+                               csc_coeff[2][2] = 0x2000;
+                               csc_coeff[2][3] = 0x0200;
+
+                               csc_scale = 0;
+                               coeff_selected = true;
+                       }
+               }
+       }
+
+       if (!coeff_selected) {
+               csc_coeff[0][0] = 0x2000;
+               csc_coeff[0][1] = 0x0000;
+               csc_coeff[0][2] = 0x0000;
+               csc_coeff[0][3] = 0x0000;
+
+               csc_coeff[1][0] = 0x0000;
+               csc_coeff[1][1] = 0x2000;
+               csc_coeff[1][2] = 0x0000;
+               csc_coeff[1][3] = 0x0000;
+
+               csc_coeff[2][0] = 0x0000;
+               csc_coeff[2][1] = 0x0000;
+               csc_coeff[2][2] = 0x2000;
+               csc_coeff[2][3] = 0x0000;
+
+               csc_scale = 1;
+       }
+
+       /* Update CSC parameters in HDMI CSC registers */
+       hdmi_writeb((unsigned char)(csc_coeff[0][0] & 0xFF),
+               HDMI_CSC_COEF_A1_LSB);
+       hdmi_writeb((unsigned char)(csc_coeff[0][0] >> 8),
+               HDMI_CSC_COEF_A1_MSB);
+       hdmi_writeb((unsigned char)(csc_coeff[0][1] & 0xFF),
+               HDMI_CSC_COEF_A2_LSB);
+       hdmi_writeb((unsigned char)(csc_coeff[0][1] >> 8),
+               HDMI_CSC_COEF_A2_MSB);
+       hdmi_writeb((unsigned char)(csc_coeff[0][2] & 0xFF),
+               HDMI_CSC_COEF_A3_LSB);
+       hdmi_writeb((unsigned char)(csc_coeff[0][2] >> 8),
+               HDMI_CSC_COEF_A3_MSB);
+       hdmi_writeb((unsigned char)(csc_coeff[0][3] & 0xFF),
+               HDMI_CSC_COEF_A4_LSB);
+       hdmi_writeb((unsigned char)(csc_coeff[0][3] >> 8),
+               HDMI_CSC_COEF_A4_MSB);
+
+       hdmi_writeb((unsigned char)(csc_coeff[1][0] & 0xFF),
+               HDMI_CSC_COEF_B1_LSB);
+       hdmi_writeb((unsigned char)(csc_coeff[1][0] >> 8),
+               HDMI_CSC_COEF_B1_MSB);
+       hdmi_writeb((unsigned char)(csc_coeff[1][1] & 0xFF),
+               HDMI_CSC_COEF_B2_LSB);
+       hdmi_writeb((unsigned char)(csc_coeff[1][1] >> 8),
+               HDMI_CSC_COEF_B2_MSB);
+       hdmi_writeb((unsigned char)(csc_coeff[1][2] & 0xFF),
+               HDMI_CSC_COEF_B3_LSB);
+       hdmi_writeb((unsigned char)(csc_coeff[1][2] >> 8),
+               HDMI_CSC_COEF_B3_MSB);
+       hdmi_writeb((unsigned char)(csc_coeff[1][3] & 0xFF),
+               HDMI_CSC_COEF_B4_LSB);
+       hdmi_writeb((unsigned char)(csc_coeff[1][3] >> 8),
+               HDMI_CSC_COEF_B4_MSB);
+
+       hdmi_writeb((unsigned char)(csc_coeff[2][0] & 0xFF),
+               HDMI_CSC_COEF_C1_LSB);
+       hdmi_writeb((unsigned char)(csc_coeff[2][0] >> 8),
+               HDMI_CSC_COEF_C1_MSB);
+       hdmi_writeb((unsigned char)(csc_coeff[2][1] & 0xFF),
+               HDMI_CSC_COEF_C2_LSB);
+       hdmi_writeb((unsigned char)(csc_coeff[2][1] >> 8),
+               HDMI_CSC_COEF_C2_MSB);
+       hdmi_writeb((unsigned char)(csc_coeff[2][2] & 0xFF),
+               HDMI_CSC_COEF_C3_LSB);
+       hdmi_writeb((unsigned char)(csc_coeff[2][2] >> 8),
+               HDMI_CSC_COEF_C3_MSB);
+       hdmi_writeb((unsigned char)(csc_coeff[2][3] & 0xFF),
+               HDMI_CSC_COEF_C4_LSB);
+       hdmi_writeb((unsigned char)(csc_coeff[2][3] >> 8),
+               HDMI_CSC_COEF_C4_MSB);
+
+       val = hdmi_readb(HDMI_CSC_SCALE);
+       val &= ~HDMI_CSC_SCALE_CSCSCALE_MASK;
+       val |= csc_scale & HDMI_CSC_SCALE_CSCSCALE_MASK;
+       hdmi_writeb(val, HDMI_CSC_SCALE);
+}
+
+static void hdmi_video_csc(struct mxc_hdmi *hdmi)
+{
+       int color_depth = 0;
+       int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
+       int decimation = 0;
+       u8 val;
+
+       /* YCC422 interpolation to 444 mode */
+       if (isColorSpaceInterpolation(hdmi))
+               interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1;
+       else if (isColorSpaceDecimation(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(interpolation | decimation, HDMI_CSC_CFG);
+       val = hdmi_readb(HDMI_CSC_SCALE);
+       val &= ~HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK;
+       val |= color_depth;
+       hdmi_writeb(val, HDMI_CSC_SCALE);
+
+       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 mxc_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;
+
+       if (hdmi_data->enc_out_format == RGB
+               || hdmi_data->enc_out_format == YCBCR444) {
+               if (hdmi_data->enc_color_depth == 0)
+                       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 == 0 ||
+                       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;
+
+       /* HDMI not support deep color,
+        * because IPU MAX support color depth is 24bit */
+       color_depth = 0;
+
+       /* 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(val, HDMI_VP_PR_CD);
+
+       val = hdmi_readb(HDMI_VP_STUFF);
+       val &= ~HDMI_VP_STUFF_PR_STUFFING_MASK;
+       val |= HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE;
+       hdmi_writeb(val, HDMI_VP_STUFF);
+
+       /* Data from pixel repeater block */
+       if (hdmi_data->pix_repet_factor > 1) {
+               val = hdmi_readb(HDMI_VP_CONF);
+               val &= ~(HDMI_VP_CONF_PR_EN_MASK |
+                       HDMI_VP_CONF_BYPASS_SELECT_MASK);
+               val |= HDMI_VP_CONF_PR_EN_ENABLE |
+                       HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER;
+               hdmi_writeb(val, HDMI_VP_CONF);
+       } else { /* data from packetizer block */
+               val = hdmi_readb(HDMI_VP_CONF);
+               val &= ~(HDMI_VP_CONF_PR_EN_MASK |
+                       HDMI_VP_CONF_BYPASS_SELECT_MASK);
+               val |= HDMI_VP_CONF_PR_EN_DISABLE |
+                       HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
+               hdmi_writeb(val, HDMI_VP_CONF);
+       }
+
+       val = hdmi_readb(HDMI_VP_STUFF);
+       val &= ~HDMI_VP_STUFF_IDEFAULT_PHASE_MASK;
+       val |= 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET;
+       hdmi_writeb(val, HDMI_VP_STUFF);
+
+       hdmi_writeb(remap_size, HDMI_VP_REMAP);
+
+       if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) {
+               val = hdmi_readb(HDMI_VP_CONF);
+               val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
+                       HDMI_VP_CONF_PP_EN_ENMASK |
+                       HDMI_VP_CONF_YCC422_EN_MASK);
+               val |= HDMI_VP_CONF_BYPASS_EN_DISABLE |
+                       HDMI_VP_CONF_PP_EN_ENABLE |
+                       HDMI_VP_CONF_YCC422_EN_DISABLE;
+               hdmi_writeb(val, HDMI_VP_CONF);
+       } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) {
+               val = hdmi_readb(HDMI_VP_CONF);
+               val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
+                       HDMI_VP_CONF_PP_EN_ENMASK |
+                       HDMI_VP_CONF_YCC422_EN_MASK);
+               val |= HDMI_VP_CONF_BYPASS_EN_DISABLE |
+                       HDMI_VP_CONF_PP_EN_DISABLE |
+                       HDMI_VP_CONF_YCC422_EN_ENABLE;
+               hdmi_writeb(val, HDMI_VP_CONF);
+       } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) {
+               val = hdmi_readb(HDMI_VP_CONF);
+               val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
+                       HDMI_VP_CONF_PP_EN_ENMASK |
+                       HDMI_VP_CONF_YCC422_EN_MASK);
+               val |= HDMI_VP_CONF_BYPASS_EN_ENABLE |
+                       HDMI_VP_CONF_PP_EN_DISABLE |
+                       HDMI_VP_CONF_YCC422_EN_DISABLE;
+               hdmi_writeb(val, HDMI_VP_CONF);
+       } else {
+               return;
+       }
+
+       val = hdmi_readb(HDMI_VP_STUFF);
+       val &= ~(HDMI_VP_STUFF_PP_STUFFING_MASK |
+               HDMI_VP_STUFF_YCC422_STUFFING_MASK);
+       val |= HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
+               HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE;
+       hdmi_writeb(val, HDMI_VP_STUFF);
+
+       val = hdmi_readb(HDMI_VP_CONF);
+       val &= ~HDMI_VP_CONF_OUTPUT_SELECTOR_MASK;
+       val |= output_select;
+       hdmi_writeb(val, HDMI_VP_CONF);
+}
+
+#if 0
+/* Force a fixed color screen */
+static void hdmi_video_force_output(struct mxc_hdmi *hdmi, unsigned char force)
+{
+       u8 val;
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       if (force) {
+               hdmi_writeb(0x00, HDMI_FC_DBGTMDS2);   /* R */
+               hdmi_writeb(0x00, HDMI_FC_DBGTMDS1);   /* G */
+               hdmi_writeb(0xFF, HDMI_FC_DBGTMDS0);   /* B */
+               val = hdmi_readb(HDMI_FC_DBGFORCE);
+               val |= HDMI_FC_DBGFORCE_FORCEVIDEO;
+               hdmi_writeb(val, HDMI_FC_DBGFORCE);
+       } else {
+               val = hdmi_readb(HDMI_FC_DBGFORCE);
+               val &= ~HDMI_FC_DBGFORCE_FORCEVIDEO;
+               hdmi_writeb(val, HDMI_FC_DBGFORCE);
+               hdmi_writeb(0x00, HDMI_FC_DBGTMDS2);   /* R */
+               hdmi_writeb(0x00, HDMI_FC_DBGTMDS1);   /* G */
+               hdmi_writeb(0x00, HDMI_FC_DBGTMDS0);   /* B */
+       }
+}
+#endif
+
+static inline void hdmi_phy_test_clear(struct mxc_hdmi *hdmi,
+                                               unsigned char bit)
+{
+       u8 val = hdmi_readb(HDMI_PHY_TST0);
+       val &= ~HDMI_PHY_TST0_TSTCLR_MASK;
+       val |= (bit << HDMI_PHY_TST0_TSTCLR_OFFSET) &
+               HDMI_PHY_TST0_TSTCLR_MASK;
+       hdmi_writeb(val, HDMI_PHY_TST0);
+}
+
+static inline void hdmi_phy_test_enable(struct mxc_hdmi *hdmi,
+                                               unsigned char bit)
+{
+       u8 val = hdmi_readb(HDMI_PHY_TST0);
+       val &= ~HDMI_PHY_TST0_TSTEN_MASK;
+       val |= (bit << HDMI_PHY_TST0_TSTEN_OFFSET) &
+               HDMI_PHY_TST0_TSTEN_MASK;
+       hdmi_writeb(val, HDMI_PHY_TST0);
+}
+
+static inline void hdmi_phy_test_clock(struct mxc_hdmi *hdmi,
+                                               unsigned char bit)
+{
+       u8 val = hdmi_readb(HDMI_PHY_TST0);
+       val &= ~HDMI_PHY_TST0_TSTCLK_MASK;
+       val |= (bit << HDMI_PHY_TST0_TSTCLK_OFFSET) &
+               HDMI_PHY_TST0_TSTCLK_MASK;
+       hdmi_writeb(val, HDMI_PHY_TST0);
+}
+
+static inline void hdmi_phy_test_din(struct mxc_hdmi *hdmi,
+                                               unsigned char bit)
+{
+       hdmi_writeb(bit, HDMI_PHY_TST1);
+}
+
+static inline void hdmi_phy_test_dout(struct mxc_hdmi *hdmi,
+                                               unsigned char bit)
+{
+       hdmi_writeb(bit, HDMI_PHY_TST2);
+}
+
+static bool hdmi_phy_wait_i2c_done(struct mxc_hdmi *hdmi, int msec)
+{
+       unsigned char val = 0;
+       val = hdmi_readb(HDMI_IH_I2CMPHY_STAT0) & 0x3;
+       while (val == 0) {
+               udelay(1000);
+               if (msec-- == 0)
+                       return false;
+               val = hdmi_readb(HDMI_IH_I2CMPHY_STAT0) & 0x3;
+       }
+       return true;
+}
+
+static void hdmi_phy_i2c_write(struct mxc_hdmi *hdmi, unsigned short data,
+                             unsigned char addr)
+{
+       hdmi_writeb(0xFF, HDMI_IH_I2CMPHY_STAT0);
+       hdmi_writeb(addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
+       hdmi_writeb((unsigned char)(data >> 8),
+               HDMI_PHY_I2CM_DATAO_1_ADDR);
+       hdmi_writeb((unsigned char)(data >> 0),
+               HDMI_PHY_I2CM_DATAO_0_ADDR);
+       hdmi_writeb(HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
+               HDMI_PHY_I2CM_OPERATION_ADDR);
+       hdmi_phy_wait_i2c_done(hdmi, 1000);
+}
+
+#if 0
+static unsigned short hdmi_phy_i2c_read(struct mxc_hdmi *hdmi,
+                                       unsigned char addr)
+{
+       unsigned short data;
+       unsigned char msb = 0, lsb = 0;
+       hdmi_writeb(0xFF, HDMI_IH_I2CMPHY_STAT0);
+       hdmi_writeb(addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
+       hdmi_writeb(HDMI_PHY_I2CM_OPERATION_ADDR_READ,
+               HDMI_PHY_I2CM_OPERATION_ADDR);
+       hdmi_phy_wait_i2c_done(hdmi, 1000);
+       msb = hdmi_readb(HDMI_PHY_I2CM_DATAI_1_ADDR);
+       lsb = hdmi_readb(HDMI_PHY_I2CM_DATAI_0_ADDR);
+       data = (msb << 8) | lsb;
+       return data;
+}
+
+static int hdmi_phy_i2c_write_verify(struct mxc_hdmi *hdmi, unsigned short data,
+                                    unsigned char addr)
+{
+       unsigned short val = 0;
+       hdmi_phy_i2c_write(hdmi, data, addr);
+       val = hdmi_phy_i2c_read(hdmi, addr);
+       return (val == data);
+}
+#endif
+
+static bool  hdmi_edid_wait_i2c_done(struct mxc_hdmi *hdmi, int msec)
+{
+    unsigned char val = 0;
+    val = hdmi_readb(HDMI_IH_I2CM_STAT0) & 0x2;
+    while (val == 0) {
+
+               udelay(1000);
+               if (msec-- == 0) {
+                       dev_dbg(&hdmi->pdev->dev,
+                                       "HDMI EDID i2c operation time out!!\n");
+                       return false;
+               }
+               val = hdmi_readb(HDMI_IH_I2CM_STAT0) & 0x2;
+       }
+       return true;
+}
+
+static u8 hdmi_edid_i2c_read(struct mxc_hdmi *hdmi,
+                                       u8 addr, u8 blockno)
+{
+       u8 spointer = blockno / 2;
+       u8 edidaddress = ((blockno % 2) * 0x80) + addr;
+       u8 data;
+
+       hdmi_writeb(0xFF, HDMI_IH_I2CM_STAT0);
+       hdmi_writeb(edidaddress, HDMI_I2CM_ADDRESS);
+       hdmi_writeb(spointer, HDMI_I2CM_SEGADDR);
+       if (spointer == 0)
+               hdmi_writeb(HDMI_I2CM_OPERATION_READ,
+                       HDMI_I2CM_OPERATION);
+       else
+               hdmi_writeb(HDMI_I2CM_OPERATION_READ_EXT,
+                       HDMI_I2CM_OPERATION);
+
+       hdmi_edid_wait_i2c_done(hdmi, 1000);
+       data = hdmi_readb(HDMI_I2CM_DATAI);
+       hdmi_writeb(0xFF, HDMI_IH_I2CM_STAT0);
+       return data;
+}
+
+
+/* "Power-down enable (active low)"
+ * That mean that power up == 1! */
+static void mxc_hdmi_phy_enable_power(u8 enable)
+{
+       hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
+                       HDMI_PHY_CONF0_PDZ_OFFSET,
+                       HDMI_PHY_CONF0_PDZ_MASK);
+}
+
+static void mxc_hdmi_phy_enable_tmds(u8 enable)
+{
+       hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
+                       HDMI_PHY_CONF0_ENTMDS_OFFSET,
+                       HDMI_PHY_CONF0_ENTMDS_MASK);
+}
+
+static void mxc_hdmi_phy_gen2_pddq(u8 enable)
+{
+       hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
+                       HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
+                       HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
+}
+
+static void mxc_hdmi_phy_gen2_txpwron(u8 enable)
+{
+       hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
+                       HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
+                       HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
+}
+
+#if 0
+static void mxc_hdmi_phy_gen2_enhpdrxsense(u8 enable)
+{
+       hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
+                       HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET,
+                       HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK);
+}
+#endif
+
+static void mxc_hdmi_phy_sel_data_en_pol(u8 enable)
+{
+       hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
+                       HDMI_PHY_CONF0_SELDATAENPOL_OFFSET,
+                       HDMI_PHY_CONF0_SELDATAENPOL_MASK);
+}
+
+static void mxc_hdmi_phy_sel_interface_control(u8 enable)
+{
+       hdmi_mask_writeb(enable, HDMI_PHY_CONF0,
+                       HDMI_PHY_CONF0_SELDIPIF_OFFSET,
+                       HDMI_PHY_CONF0_SELDIPIF_MASK);
+}
+
+static int hdmi_phy_configure(struct mxc_hdmi *hdmi, unsigned char pRep,
+                             unsigned char cRes, int cscOn)
+{
+       u8 val;
+       u8 msec;
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       /* color resolution 0 is 8 bit colour depth */
+       if (cRes == 0)
+               cRes = 8;
+
+       if (pRep != 0)
+               return false;
+       else if (cRes != 8 && cRes != 12)
+               return false;
+
+       /* 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(val, HDMI_MC_FLOWCTRL);
+
+       /* gen2 tx power off */
+       mxc_hdmi_phy_gen2_txpwron(0);
+
+       /* gen2 pddq */
+       mxc_hdmi_phy_gen2_pddq(1);
+
+       /* PHY reset */
+       hdmi_writeb(HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
+       hdmi_writeb(HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
+
+       hdmi_writeb(HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
+
+       hdmi_phy_test_clear(hdmi, 1);
+       hdmi_writeb(HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
+                       HDMI_PHY_I2CM_SLAVE_ADDR);
+       hdmi_phy_test_clear(hdmi, 0);
+
+       if (hdmi->hdmi_data.video_mode.mPixelClock < 0) {
+               dev_dbg(&hdmi->pdev->dev, "Pixel clock (%d) must be positive\n",
+                       hdmi->hdmi_data.video_mode.mPixelClock);
+               return false;
+       }
+
+       if (hdmi->hdmi_data.video_mode.mPixelClock <= 45250000) {
+               switch (cRes) {
+               case 8:
+                       /* PLL/MPLL Cfg */
+                       hdmi_phy_i2c_write(hdmi, 0x01e0, 0x06);
+                       hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);  /* GMPCTRL */
+                       break;
+               case 10:
+                       hdmi_phy_i2c_write(hdmi, 0x21e1, 0x06);
+                       hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
+                       break;
+               case 12:
+                       hdmi_phy_i2c_write(hdmi, 0x41e2, 0x06);
+                       hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
+                       break;
+               default:
+                       return false;
+               }
+       } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 92500000) {
+               switch (cRes) {
+               case 8:
+                       hdmi_phy_i2c_write(hdmi, 0x0140, 0x06);
+                       hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
+                       break;
+               case 10:
+                       hdmi_phy_i2c_write(hdmi, 0x2141, 0x06);
+                       hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
+                       break;
+               case 12:
+                       hdmi_phy_i2c_write(hdmi, 0x4142, 0x06);
+                       hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
+               default:
+                       return false;
+               }
+       } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 148500000) {
+               switch (cRes) {
+               case 8:
+                       hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06);
+                       hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
+                       break;
+               case 10:
+                       hdmi_phy_i2c_write(hdmi, 0x20a1, 0x06);
+                       hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
+                       break;
+               case 12:
+                       hdmi_phy_i2c_write(hdmi, 0x40a2, 0x06);
+                       hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
+               default:
+                       return false;
+               }
+       } else {
+               switch (cRes) {
+               case 8:
+                       hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06);
+                       hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
+                       break;
+               case 10:
+                       hdmi_phy_i2c_write(hdmi, 0x2001, 0x06);
+                       hdmi_phy_i2c_write(hdmi, 0x000f, 0x15);
+                       break;
+               case 12:
+                       hdmi_phy_i2c_write(hdmi, 0x4002, 0x06);
+                       hdmi_phy_i2c_write(hdmi, 0x000f, 0x15);
+               default:
+                       return false;
+               }
+       }
+
+       if (hdmi->hdmi_data.video_mode.mPixelClock <= 54000000) {
+               switch (cRes) {
+               case 8:
+                       hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);  /* CURRCTRL */
+                       break;
+               case 10:
+                       hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
+                       break;
+               case 12:
+                       hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
+                       break;
+               default:
+                       return false;
+               }
+       } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 58400000) {
+               switch (cRes) {
+               case 8:
+                       hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
+                       break;
+               case 10:
+                       hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
+                       break;
+               case 12:
+                       hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
+                       break;
+               default:
+                       return false;
+               }
+       } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 72000000) {
+               switch (cRes) {
+               case 8:
+                       hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
+                       break;
+               case 10:
+                       hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
+                       break;
+               case 12:
+                       hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
+                       break;
+               default:
+                       return false;
+               }
+       } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 74250000) {
+               switch (cRes) {
+               case 8:
+                       hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
+                       break;
+               case 10:
+                       hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10);
+                       break;
+               case 12:
+                       hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
+                       break;
+               default:
+                       return false;
+               }
+       } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 118800000) {
+               switch (cRes) {
+               case 8:
+                       hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
+                       break;
+               case 10:
+                       hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
+                       break;
+               case 12:
+                       hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
+                       break;
+               default:
+                       return false;
+               }
+       } else if (hdmi->hdmi_data.video_mode.mPixelClock <= 216000000) {
+               switch (cRes) {
+               case 8:
+                       hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
+                       break;
+               case 10:
+                       hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10);
+                       break;
+               case 12:
+                       hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
+                       break;
+               default:
+                       return false;
+               }
+       } else {
+               dev_err(&hdmi->pdev->dev,
+                               "Pixel clock %d - unsupported by HDMI\n",
+                               hdmi->hdmi_data.video_mode.mPixelClock);
+               return false;
+       }
+
+       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 */
+
+       /* Board specific setting for PHY register 0x09, 0x0e to pass HCT */
+       if (hdmi->phy_config.reg_cksymtx != 0)
+               hdmi_phy_i2c_write(hdmi, hdmi->phy_config.reg_cksymtx, 0x09);
+
+       if (hdmi->phy_config.reg_vlev != 0)
+               hdmi_phy_i2c_write(hdmi, hdmi->phy_config.reg_vlev, 0x0E);
+
+       /* REMOVE CLK TERM */
+       hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);  /* CKCALCTRL */
+
+       if (hdmi->hdmi_data.video_mode.mPixelClock > 148500000) {
+                       hdmi_phy_i2c_write(hdmi, 0x800b, 0x09);
+                       hdmi_phy_i2c_write(hdmi, 0x0129, 0x0E);
+       }
+
+       mxc_hdmi_phy_enable_power(1);
+
+       /* toggle TMDS enable */
+       mxc_hdmi_phy_enable_tmds(0);
+       mxc_hdmi_phy_enable_tmds(1);
+
+       /* gen2 tx power on */
+       mxc_hdmi_phy_gen2_txpwron(1);
+       mxc_hdmi_phy_gen2_pddq(0);
+
+       /*Wait for PHY PLL lock */
+       msec = 4;
+       val = hdmi_readb(HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
+       while (val == 0) {
+               udelay(1000);
+               if (msec-- == 0) {
+                       dev_dbg(&hdmi->pdev->dev, "PHY PLL not locked\n");
+                       return false;
+               }
+               val = hdmi_readb(HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
+       }
+
+       return true;
+}
+
+static void mxc_hdmi_phy_init(struct mxc_hdmi *hdmi)
+{
+       int i;
+       bool cscon = false;
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       /* Never do phy init if pixel clock is gated.
+        * Otherwise HDMI PHY will get messed up and generate an overflow
+        * interrupt that can't be cleared or detected by accessing the
+        * status register. */
+       if (!hdmi->fb_reg || !hdmi->cable_plugin
+                       || (hdmi->blank != FB_BLANK_UNBLANK))
+               return;
+
+       /*check csc whether needed activated in HDMI mode */
+       cscon = (isColorSpaceConversion(hdmi) &&
+                       !hdmi->hdmi_data.video_mode.mDVI);
+
+       /* HDMI Phy spec says to do the phy initialization sequence twice */
+       for (i = 0 ; i < 2 ; i++) {
+               mxc_hdmi_phy_sel_data_en_pol(1);
+               mxc_hdmi_phy_sel_interface_control(0);
+               mxc_hdmi_phy_enable_tmds(0);
+               mxc_hdmi_phy_enable_power(0);
+
+               /* Enable CSC */
+               hdmi_phy_configure(hdmi, 0, 8, cscon);
+       }
+
+       hdmi->phy_enabled = true;
+}
+
+static void hdmi_tx_hdcp_config(struct mxc_hdmi *hdmi)
+{
+#if 0
+       if (hdmi->hdmi_data.hdcp_enable) {
+               /* Enable HDMI DDC pin */
+               mxc_hdmi_enable_pins(hdmi);
+       } else {
+               /* Disable HDMI DDC pin */
+               mxc_hdmi_disable_pins(hdmi);
+       }
+#endif
+}
+
+static void hdmi_config_AVI(struct mxc_hdmi *hdmi)
+{
+       u8 val;
+       u8 pix_fmt;
+       u8 under_scan;
+       u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry;
+       struct fb_videomode mode;
+       const struct fb_videomode *edid_mode;
+       bool aspect_16_9;
+
+       dev_dbg(&hdmi->pdev->dev, "set up AVI frame\n");
+
+       fb_var_to_videomode(&mode, &hdmi->fbi->var);
+       /* Use mode from list extracted from EDID to get aspect ratio */
+       if (!list_empty(&hdmi->fbi->modelist)) {
+               edid_mode = fb_find_nearest_mode(&mode, &hdmi->fbi->modelist);
+               if (edid_mode->vmode & FB_VMODE_ASPECT_16_9)
+                       aspect_16_9 = true;
+               else
+                       aspect_16_9 = false;
+       } else
+               aspect_16_9 = false;
+
+       /********************************************
+        * 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;
+
+       if (hdmi->edid_cfg.cea_underscan)
+               under_scan = HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN;
+       else
+               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(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 == eITU601)
+                       ext_colorimetry =
+                               HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
+               else /* hdmi->hdmi_data.colorimetry == eITU709 */
+                       ext_colorimetry =
+                               HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709;
+       } else if (hdmi->hdmi_data.enc_out_format != RGB) {
+               if (hdmi->hdmi_data.colorimetry == eITU601)
+                       colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE;
+               else /* hdmi->hdmi_data.colorimetry == eITU709 */
+                       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(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(val, HDMI_FC_AVICONF2);
+
+       /********************************************
+        * AVI Data Byte 4
+        ********************************************/
+       hdmi_writeb(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(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(val, HDMI_FC_AVICONF3);
+
+       /********************************************
+        * AVI Data Bytes 6-13
+        ********************************************/
+       hdmi_writeb(0, HDMI_FC_AVIETB0);
+       hdmi_writeb(0, HDMI_FC_AVIETB1);
+       hdmi_writeb(0, HDMI_FC_AVISBB0);
+       hdmi_writeb(0, HDMI_FC_AVISBB1);
+       hdmi_writeb(0, HDMI_FC_AVIELB0);
+       hdmi_writeb(0, HDMI_FC_AVIELB1);
+       hdmi_writeb(0, HDMI_FC_AVISRB0);
+       hdmi_writeb(0, HDMI_FC_AVISRB1);
+}
+
+/*!
+ * this submodule is responsible for the video/audio data composition.
+ */
+static void hdmi_av_composer(struct mxc_hdmi *hdmi)
+{
+       u8 inv_val;
+       struct fb_info *fbi = hdmi->fbi;
+       struct fb_videomode fb_mode;
+       struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
+       int hblank, vblank;
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       fb_var_to_videomode(&fb_mode, &fbi->var);
+
+       vmode->mHSyncPolarity = ((fb_mode.sync & FB_SYNC_HOR_HIGH_ACT) != 0);
+       vmode->mVSyncPolarity = ((fb_mode.sync & FB_SYNC_VERT_HIGH_ACT) != 0);
+       vmode->mInterlaced = ((fb_mode.vmode & FB_VMODE_INTERLACED) != 0);
+       vmode->mPixelClock = (fb_mode.xres + fb_mode.left_margin +
+               fb_mode.right_margin + fb_mode.hsync_len) * (fb_mode.yres +
+               fb_mode.upper_margin + fb_mode.lower_margin +
+               fb_mode.vsync_len) * fb_mode.refresh;
+
+       dev_dbg(&hdmi->pdev->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(inv_val, HDMI_FC_INVIDCONF);
+
+       /* Set up horizontal active pixel region width */
+       hdmi_writeb(fb_mode.xres >> 8, HDMI_FC_INHACTV1);
+       hdmi_writeb(fb_mode.xres, HDMI_FC_INHACTV0);
+
+       /* Set up vertical blanking pixel region width */
+       hdmi_writeb(fb_mode.yres >> 8, HDMI_FC_INVACTV1);
+       hdmi_writeb(fb_mode.yres, HDMI_FC_INVACTV0);
+
+       /* Set up horizontal blanking pixel region width */
+       hblank = fb_mode.left_margin + fb_mode.right_margin +
+               fb_mode.hsync_len;
+       hdmi_writeb(hblank >> 8, HDMI_FC_INHBLANK1);
+       hdmi_writeb(hblank, HDMI_FC_INHBLANK0);
+
+       /* Set up vertical blanking pixel region width */
+       vblank = fb_mode.upper_margin + fb_mode.lower_margin +
+               fb_mode.vsync_len;
+       hdmi_writeb(vblank, HDMI_FC_INVBLANK);
+
+       /* Set up HSYNC active edge delay width (in pixel clks) */
+       hdmi_writeb(fb_mode.right_margin >> 8, HDMI_FC_HSYNCINDELAY1);
+       hdmi_writeb(fb_mode.right_margin, HDMI_FC_HSYNCINDELAY0);
+
+       /* Set up VSYNC active edge delay (in pixel clks) */
+       hdmi_writeb(fb_mode.lower_margin, HDMI_FC_VSYNCINDELAY);
+
+       /* Set up HSYNC active pulse width (in pixel clks) */
+       hdmi_writeb(fb_mode.hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1);
+       hdmi_writeb(fb_mode.hsync_len, HDMI_FC_HSYNCINWIDTH0);
+
+       /* Set up VSYNC active edge delay (in pixel clks) */
+       hdmi_writeb(fb_mode.vsync_len, HDMI_FC_VSYNCINWIDTH);
+
+       dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
+}
+
+static int mxc_edid_read_internal(struct mxc_hdmi *hdmi, unsigned char *edid,
+                       struct mxc_edid_cfg *cfg, struct fb_info *fbi)
+{
+       int extblknum;
+       int i, j, ret;
+       unsigned char *ediddata = edid;
+       unsigned char tmpedid[EDID_LENGTH];
+
+       dev_info(&hdmi->pdev->dev, "%s\n", __func__);
+
+       if (!edid || !cfg || !fbi)
+               return -EINVAL;
+
+       /* init HDMI I2CM for read edid*/
+       hdmi_writeb(0x0, HDMI_I2CM_DIV);
+       hdmi_writeb(0x00, HDMI_I2CM_SS_SCL_HCNT_1_ADDR);
+       hdmi_writeb(0x79, HDMI_I2CM_SS_SCL_HCNT_0_ADDR);
+       hdmi_writeb(0x00, HDMI_I2CM_SS_SCL_LCNT_1_ADDR);
+       hdmi_writeb(0x91, HDMI_I2CM_SS_SCL_LCNT_0_ADDR);
+
+       hdmi_writeb(0x00, HDMI_I2CM_FS_SCL_HCNT_1_ADDR);
+       hdmi_writeb(0x0F, HDMI_I2CM_FS_SCL_HCNT_0_ADDR);
+       hdmi_writeb(0x00, HDMI_I2CM_FS_SCL_LCNT_1_ADDR);
+       hdmi_writeb(0x21, HDMI_I2CM_FS_SCL_LCNT_0_ADDR);
+
+       hdmi_writeb(0x50, HDMI_I2CM_SLAVE);
+       hdmi_writeb(0x30, HDMI_I2CM_SEGADDR);
+
+       /* Umask edid interrupt */
+       hdmi_writeb(HDMI_I2CM_INT_DONE_POL,
+                   HDMI_I2CM_INT);
+
+       hdmi_writeb(HDMI_I2CM_CTLINT_NAC_POL |
+                   HDMI_I2CM_CTLINT_ARBITRATION_POL,
+                   HDMI_I2CM_CTLINT);
+
+       /* reset edid data zero */
+       memset(edid, 0, EDID_LENGTH*4);
+       memset(cfg, 0, sizeof(struct mxc_edid_cfg));
+
+       /* Check first three byte of EDID head */
+       if (!(hdmi_edid_i2c_read(hdmi, 0, 0) == 0x00) ||
+               !(hdmi_edid_i2c_read(hdmi, 1, 0) == 0xFF) ||
+               !(hdmi_edid_i2c_read(hdmi, 2, 0) == 0xFF)) {
+               dev_info(&hdmi->pdev->dev, "EDID head check failed!");
+               return -ENOENT;
+       }
+
+       for (i = 0; i < 128; i++) {
+               *ediddata = hdmi_edid_i2c_read(hdmi, i, 0);
+               ediddata++;
+       }
+
+       extblknum = edid[0x7E];
+       if (extblknum < 0)
+               return extblknum;
+
+       if (extblknum) {
+               ediddata = edid + EDID_LENGTH;
+               for (i = 0; i < 128; i++) {
+                       *ediddata = hdmi_edid_i2c_read(hdmi, i, 1);
+                       ediddata++;
+               }
+       }
+
+       /* edid first block parsing */
+       memset(&fbi->monspecs, 0, sizeof(fbi->monspecs));
+       fb_edid_to_monspecs(edid, &fbi->monspecs);
+
+       ret = mxc_edid_parse_ext_blk(edid + EDID_LENGTH,
+                       cfg, &fbi->monspecs);
+       if (ret < 0)
+               return -ENOENT;
+
+       /* need read segment block? */
+       if (extblknum > 1) {
+               for (j = 1; j <= extblknum; j++) {
+                       for (i = 0; i < 128; i++)
+                               *(tmpedid + 1) = hdmi_edid_i2c_read(hdmi, i, j);
+
+                       /* edid ext block parsing */
+                       ret = mxc_edid_parse_ext_blk(tmpedid + EDID_LENGTH,
+                                       cfg, &fbi->monspecs);
+                       if (ret < 0)
+                               return -ENOENT;
+               }
+       }
+
+       return 0;
+}
+
+static int mxc_hdmi_read_edid(struct mxc_hdmi *hdmi)
+{
+       int ret;
+       u8 edid_old[HDMI_EDID_LEN];
+       u8 clkdis;
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       /* save old edid */
+       memcpy(edid_old, hdmi->edid, HDMI_EDID_LEN);
+
+       /* Read EDID via HDMI DDC when HDCP Enable */
+       if (!hdcp_init)
+               ret = mxc_edid_read(hdmi_i2c->adapter, hdmi_i2c->addr,
+                               hdmi->edid, &hdmi->edid_cfg, hdmi->fbi);
+       else {
+
+               /* Disable HDCP clk */
+               if (hdmi->hdmi_data.hdcp_enable) {
+                       clkdis = hdmi_readb(HDMI_MC_CLKDIS);
+                       clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE;
+                       hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
+               }
+
+               ret = mxc_edid_read_internal(hdmi, hdmi->edid,
+                               &hdmi->edid_cfg, hdmi->fbi);
+
+               /* Enable HDCP clk */
+               if (hdmi->hdmi_data.hdcp_enable) {
+                       clkdis = hdmi_readb(HDMI_MC_CLKDIS);
+                       clkdis &= ~HDMI_MC_CLKDIS_HDCPCLK_DISABLE;
+                       hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
+               }
+
+       }
+       if (ret < 0)
+               return HDMI_EDID_FAIL;
+
+       /* Save edid cfg for audio driver */
+       hdmi_set_edid_cfg(&hdmi->edid_cfg);
+
+       if (!memcmp(edid_old, hdmi->edid, HDMI_EDID_LEN)) {
+               dev_info(&hdmi->pdev->dev, "same edid\n");
+               return HDMI_EDID_SAME;
+       }
+
+       if (hdmi->fbi->monspecs.modedb_len == 0) {
+               dev_info(&hdmi->pdev->dev, "No modes read from edid\n");
+               return HDMI_EDID_NO_MODES;
+       }
+
+       return HDMI_EDID_SUCCESS;
+}
+
+#if 0
+static void mxc_hdmi_enable_pins(struct mxc_hdmi *hdmi)
+{
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+}
+
+static void mxc_hdmi_disable_pins(struct mxc_hdmi *hdmi)
+{
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+}
+#endif
+
+static void mxc_hdmi_phy_disable(struct mxc_hdmi *hdmi)
+{
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       if (!hdmi->phy_enabled)
+               return;
+
+       /* Setting PHY to reset status */
+       hdmi_writeb(HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
+
+       /* Power down PHY */
+       mxc_hdmi_phy_enable_tmds(0);
+       mxc_hdmi_phy_enable_power(0);
+       mxc_hdmi_phy_gen2_txpwron(0);
+       mxc_hdmi_phy_gen2_pddq(1);
+
+       hdmi->phy_enabled = false;
+       dev_dbg(&hdmi->pdev->dev, "%s - exit\n", __func__);
+}
+
+/* HDMI Initialization Step B.4 */
+static void mxc_hdmi_enable_video_path(struct mxc_hdmi *hdmi)
+{
+       u8 clkdis;
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       /* control period minimum duration */
+       hdmi_writeb(12, HDMI_FC_CTRLDUR);
+       hdmi_writeb(32, HDMI_FC_EXCTRLDUR);
+       hdmi_writeb(1, HDMI_FC_EXCTRLSPAC);
+
+       /* Set to fill TMDS data channels */
+       hdmi_writeb(0x0B, HDMI_FC_CH0PREAM);
+       hdmi_writeb(0x16, HDMI_FC_CH1PREAM);
+       hdmi_writeb(0x21, HDMI_FC_CH2PREAM);
+
+       /* Enable pixel clock and tmds data path */
+       clkdis = 0x7F;
+       clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
+       hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
+
+       clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
+       hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
+
+       /* Enable csc path */
+       if (isColorSpaceConversion(hdmi)) {
+               clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
+               hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
+       }
+}
+
+static void hdmi_enable_audio_clk(struct mxc_hdmi *hdmi)
+{
+       u8 clkdis;
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       clkdis = hdmi_readb(HDMI_MC_CLKDIS);
+       clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
+       hdmi_writeb(clkdis, HDMI_MC_CLKDIS);
+}
+
+/* Workaround to clear the overflow condition */
+static void mxc_hdmi_clear_overflow(struct mxc_hdmi *hdmi)
+{
+       int count;
+       u8 val;
+
+       /* TMDS software reset */
+       hdmi_writeb((u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
+
+       val = hdmi_readb(HDMI_FC_INVIDCONF);
+
+       if (cpu_is_imx6dl(hdmi)) {
+                hdmi_writeb(val, HDMI_FC_INVIDCONF);
+                return;
+       }
+
+       for (count = 0 ; count < 5 ; count++)
+               hdmi_writeb(val, HDMI_FC_INVIDCONF);
+}
+
+static void hdmi_enable_overflow_interrupts(void)
+{
+       pr_debug("%s\n", __func__);
+       hdmi_writeb(0, HDMI_FC_MASK2);
+       hdmi_writeb(0, HDMI_IH_MUTE_FC_STAT2);
+}
+
+static void hdmi_disable_overflow_interrupts(void)
+{
+       pr_debug("%s\n", __func__);
+       hdmi_writeb(HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
+                   HDMI_IH_MUTE_FC_STAT2);
+       hdmi_writeb(0xff, HDMI_FC_MASK2);
+}
+
+static void mxc_hdmi_notify_fb(struct mxc_hdmi *hdmi)
+{
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       /* Don't notify if we aren't registered yet */
+       WARN_ON(!hdmi->fb_reg);
+
+       /* disable the phy before ipu changes mode */
+       mxc_hdmi_phy_disable(hdmi);
+
+       /*
+        * Note that fb_set_var will block.  During this time,
+        * FB_EVENT_MODE_CHANGE callback will happen.
+        * So by the end of this function, mxc_hdmi_setup()
+        * will be done.
+        */
+       hdmi->fbi->var.activate |= FB_ACTIVATE_FORCE;
+       console_lock();
+       hdmi->fbi->flags |= FBINFO_MISC_USEREVENT;
+       fb_set_var(hdmi->fbi, &hdmi->fbi->var);
+       hdmi->fbi->flags &= ~FBINFO_MISC_USEREVENT;
+       console_unlock();
+
+       dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
+}
+
+static void mxc_hdmi_edid_rebuild_modelist(struct mxc_hdmi *hdmi)
+{
+       int i;
+       struct fb_videomode *mode;
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       console_lock();
+
+       fb_destroy_modelist(&hdmi->fbi->modelist);
+       fb_add_videomode(&vga_mode, &hdmi->fbi->modelist);
+
+       for (i = 0; i < hdmi->fbi->monspecs.modedb_len; i++) {
+               /*
+                * We might check here if mode is supported by HDMI.
+                * We do not currently support interlaced modes.
+                * And add CEA modes in the modelist.
+                */
+               mode = &hdmi->fbi->monspecs.modedb[i];
+
+               if (!(mode->vmode & FB_VMODE_INTERLACED) &&
+                               (mxc_edid_mode_to_vic(mode) != 0)) {
+
+                       dev_dbg(&hdmi->pdev->dev, "Added mode %d:", i);
+                       dev_dbg(&hdmi->pdev->dev,
+                               "xres = %d, yres = %d, freq = %d, vmode = %d, flag = %d\n",
+                               hdmi->fbi->monspecs.modedb[i].xres,
+                               hdmi->fbi->monspecs.modedb[i].yres,
+                               hdmi->fbi->monspecs.modedb[i].refresh,
+                               hdmi->fbi->monspecs.modedb[i].vmode,
+                               hdmi->fbi->monspecs.modedb[i].flag);
+
+                       fb_add_videomode(mode, &hdmi->fbi->modelist);
+               }
+       }
+
+       console_unlock();
+}
+
+static void  mxc_hdmi_default_edid_cfg(struct mxc_hdmi *hdmi)
+{
+       /* Default setting HDMI working in HDMI mode */
+       hdmi->edid_cfg.hdmi_cap = true;
+}
+
+static void  mxc_hdmi_default_modelist(struct mxc_hdmi *hdmi)
+{
+       u32 i;
+       const struct fb_videomode *mode;
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       /* If not EDID data read, set up default modelist  */
+       dev_info(&hdmi->pdev->dev, "No modes read from edid\n");
+       dev_info(&hdmi->pdev->dev, "create default modelist\n");
+
+       console_lock();
+
+       fb_destroy_modelist(&hdmi->fbi->modelist);
+
+       /*Add XGA and SXGA to default modelist */
+       fb_add_videomode(&vga_mode, &hdmi->fbi->modelist);
+       fb_add_videomode(&xga_mode, &hdmi->fbi->modelist);
+       fb_add_videomode(&sxga_mode, &hdmi->fbi->modelist);
+
+       /*Add all no interlaced CEA mode to default modelist */
+       for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
+               mode = &mxc_cea_mode[i];
+               if (!(mode->vmode & FB_VMODE_INTERLACED) && (mode->xres != 0))
+                       fb_add_videomode(mode, &hdmi->fbi->modelist);
+       }
+
+       console_unlock();
+}
+
+static void mxc_hdmi_set_mode_to_vga_dvi(struct mxc_hdmi *hdmi)
+{
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       hdmi_disable_overflow_interrupts();
+
+       fb_videomode_to_var(&hdmi->fbi->var, &vga_mode);
+
+       hdmi->requesting_vga_for_initialization = true;
+       mxc_hdmi_notify_fb(hdmi);
+       hdmi->requesting_vga_for_initialization = false;
+}
+
+static void mxc_hdmi_set_mode(struct mxc_hdmi *hdmi)
+{
+       const struct fb_videomode *mode;
+       struct fb_videomode m;
+       struct fb_var_screeninfo var;
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       /* Set the default mode only once. */
+       if (!hdmi->dft_mode_set) {
+               dev_dbg(&hdmi->pdev->dev, "%s: setting to default=%s bpp=%d\n",
+                       __func__, hdmi->dft_mode_str, hdmi->default_bpp);
+
+               fb_find_mode(&var, hdmi->fbi,
+                            hdmi->dft_mode_str, NULL, 0, NULL,
+                            hdmi->default_bpp);
+
+               hdmi->dft_mode_set = true;
+       } else
+               fb_videomode_to_var(&var, &hdmi->previous_non_vga_mode);
+
+       fb_var_to_videomode(&m, &var);
+       dump_fb_videomode(&m);
+
+       mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist);
+       if (!mode) {
+               pr_err("%s: could not find mode in modelist\n", __func__);
+               return;
+       }
+
+       /* If video mode same as previous, init HDMI again */
+       if (fb_mode_is_equal(&hdmi->previous_non_vga_mode, mode)) {
+               dev_dbg(&hdmi->pdev->dev,
+                               "%s: Video mode same as previous\n", __func__);
+               /* update fbi mode in case modelist is updated */
+               hdmi->fbi->mode = (struct fb_videomode *)mode;
+               /* update hdmi setting in case EDID data updated  */
+               mxc_hdmi_setup(hdmi, 0);
+       } else {
+               dev_dbg(&hdmi->pdev->dev, "%s: New video mode\n", __func__);
+               mxc_hdmi_set_mode_to_vga_dvi(hdmi);
+               fb_videomode_to_var(&hdmi->fbi->var, mode);
+               dump_fb_videomode((struct fb_videomode *)mode);
+               mxc_hdmi_notify_fb(hdmi);
+       }
+
+}
+
+static void mxc_hdmi_cable_connected(struct mxc_hdmi *hdmi)
+{
+       int edid_status;
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       hdmi->cable_plugin = true;
+
+       /* HDMI Initialization Step C */
+       edid_status = mxc_hdmi_read_edid(hdmi);
+
+       /* Read EDID again if first EDID read failed */
+       if (edid_status == HDMI_EDID_NO_MODES ||
+                       edid_status == HDMI_EDID_FAIL) {
+               dev_info(&hdmi->pdev->dev, "Read EDID again\n");
+               edid_status = mxc_hdmi_read_edid(hdmi);
+       }
+
+       /* HDMI Initialization Steps D, E, F */
+       switch (edid_status) {
+       case HDMI_EDID_SUCCESS:
+               mxc_hdmi_edid_rebuild_modelist(hdmi);
+               break;
+
+       /* Nothing to do if EDID same */
+       case HDMI_EDID_SAME:
+               break;
+
+       case HDMI_EDID_FAIL:
+               mxc_hdmi_default_edid_cfg(hdmi);
+               /* No break here  */
+       case HDMI_EDID_NO_MODES:
+       default:
+               mxc_hdmi_default_modelist(hdmi);
+               break;
+       }
+
+       /* Setting video mode */
+       mxc_hdmi_set_mode(hdmi);
+
+       dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
+}
+
+static int mxc_hdmi_power_on(struct mxc_dispdrv_handle *disp)
+{
+       struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
+       mxc_hdmi_phy_init(hdmi);
+       return 0;
+}
+
+static void mxc_hdmi_power_off(struct mxc_dispdrv_handle *disp)
+{
+       struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
+       mxc_hdmi_phy_disable(hdmi);
+}
+
+static void mxc_hdmi_cable_disconnected(struct mxc_hdmi *hdmi)
+{
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       /* Disable All HDMI clock */
+       hdmi_writeb(0xff, HDMI_MC_CLKDIS);
+
+       mxc_hdmi_phy_disable(hdmi);
+
+       hdmi_disable_overflow_interrupts();
+
+       hdmi->cable_plugin = false;
+}
+
+static void hotplug_worker(struct work_struct *work)
+{
+       struct delayed_work *delay_work = to_delayed_work(work);
+       struct mxc_hdmi *hdmi =
+               container_of(delay_work, struct mxc_hdmi, hotplug_work);
+       u32 phy_int_stat, phy_int_pol, phy_int_mask;
+       u8 val;
+       unsigned long flags;
+       char event_string[32];
+       char *envp[] = { event_string, NULL };
+
+       phy_int_stat = hdmi->latest_intr_stat;
+       phy_int_pol = hdmi_readb(HDMI_PHY_POL0);
+
+       dev_dbg(&hdmi->pdev->dev, "phy_int_stat=0x%x, phy_int_pol=0x%x\n",
+                       phy_int_stat, phy_int_pol);
+
+       /* check cable status */
+       if (phy_int_stat & HDMI_IH_PHY_STAT0_HPD) {
+               /* cable connection changes */
+               if (phy_int_pol & HDMI_PHY_HPD) {
+                       /* Plugin event */
+                       dev_dbg(&hdmi->pdev->dev, "EVENT=plugin\n");
+                       mxc_hdmi_cable_connected(hdmi);
+
+                       /* Make HPD intr active low to capture unplug event */
+                       val = hdmi_readb(HDMI_PHY_POL0);
+                       val &= ~HDMI_PHY_HPD;
+                       hdmi_writeb(val, HDMI_PHY_POL0);
+
+                       sprintf(event_string, "EVENT=plugin");
+                       kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
+#ifdef CONFIG_MXC_HDMI_CEC
+                       mxc_hdmi_cec_handle(0x80);
+#endif
+                       hdmi_set_cable_state(1);
+
+               } else if (!(phy_int_pol & HDMI_PHY_HPD)) {
+                       /* Plugout event */
+                       dev_dbg(&hdmi->pdev->dev, "EVENT=plugout\n");
+                       hdmi_set_cable_state(0);
+                       mxc_hdmi_abort_stream();
+                       mxc_hdmi_cable_disconnected(hdmi);
+
+                       /* Make HPD intr active high to capture plugin event */
+                       val = hdmi_readb(HDMI_PHY_POL0);
+                       val |= HDMI_PHY_HPD;
+                       hdmi_writeb(val, HDMI_PHY_POL0);
+
+                       sprintf(event_string, "EVENT=plugout");
+                       kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
+#ifdef CONFIG_MXC_HDMI_CEC
+                       mxc_hdmi_cec_handle(0x100);
+#endif
+
+               } else
+                       dev_dbg(&hdmi->pdev->dev, "EVENT=none?\n");
+       }
+
+       /* Lock here to ensure full powerdown sequence
+        * completed before next interrupt processed */
+       spin_lock_irqsave(&hdmi->irq_lock, flags);
+
+       /* Re-enable HPD interrupts */
+       phy_int_mask = hdmi_readb(HDMI_PHY_MASK0);
+       phy_int_mask &= ~HDMI_PHY_HPD;
+       hdmi_writeb(phy_int_mask, HDMI_PHY_MASK0);
+
+       /* Unmute interrupts */
+       hdmi_writeb(~HDMI_IH_MUTE_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
+
+       if (hdmi_readb(HDMI_IH_FC_STAT2) & HDMI_IH_FC_STAT2_OVERFLOW_MASK)
+               mxc_hdmi_clear_overflow(hdmi);
+
+       spin_unlock_irqrestore(&hdmi->irq_lock, flags);
+}
+
+static void hdcp_hdp_worker(struct work_struct *work)
+{
+       struct delayed_work *delay_work = to_delayed_work(work);
+       struct mxc_hdmi *hdmi =
+               container_of(delay_work, struct mxc_hdmi, hdcp_hdp_work);
+       char event_string[32];
+       char *envp[] = { event_string, NULL };
+
+       /* HDCP interrupt */
+       sprintf(event_string, "EVENT=hdcpint");
+       kobject_uevent_env(&hdmi->pdev->dev.kobj, KOBJ_CHANGE, envp);
+
+       /* Unmute interrupts in HDCP application*/
+}
+
+static irqreturn_t mxc_hdmi_hotplug(int irq, void *data)
+{
+       struct mxc_hdmi *hdmi = data;
+       u8 val, intr_stat;
+       unsigned long flags;
+
+       spin_lock_irqsave(&hdmi->irq_lock, flags);
+
+       /* Check and clean packet overflow interrupt.*/
+       if (hdmi_readb(HDMI_IH_FC_STAT2) &
+                       HDMI_IH_FC_STAT2_OVERFLOW_MASK) {
+               mxc_hdmi_clear_overflow(hdmi);
+
+               dev_dbg(&hdmi->pdev->dev, "Overflow interrupt received\n");
+               /* clear irq status */
+               hdmi_writeb(HDMI_IH_FC_STAT2_OVERFLOW_MASK,
+                           HDMI_IH_FC_STAT2);
+       }
+
+       /*
+        * We could not disable the irq.  Probably the audio driver
+        * has enabled it. Masking off the HDMI interrupts using
+        * HDMI registers.
+        */
+       /* Capture status - used in hotplug_worker ISR */
+       intr_stat = hdmi_readb(HDMI_IH_PHY_STAT0);
+
+       if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
+
+               dev_dbg(&hdmi->pdev->dev, "Hotplug interrupt received\n");
+               hdmi->latest_intr_stat = intr_stat;
+
+               /* Mute interrupts until handled */
+
+               val = hdmi_readb(HDMI_IH_MUTE_PHY_STAT0);
+               val |= HDMI_IH_MUTE_PHY_STAT0_HPD;
+               hdmi_writeb(val, HDMI_IH_MUTE_PHY_STAT0);
+
+               val = hdmi_readb(HDMI_PHY_MASK0);
+               val |= HDMI_PHY_HPD;
+               hdmi_writeb(val, HDMI_PHY_MASK0);
+
+               /* Clear Hotplug interrupts */
+               hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
+
+               schedule_delayed_work(&(hdmi->hotplug_work), msecs_to_jiffies(20));
+       }
+
+       /* Check HDCP  interrupt state */
+       if (hdmi->hdmi_data.hdcp_enable) {
+               val = hdmi_readb(HDMI_A_APIINTSTAT);
+               if (val != 0) {
+                       /* Mute interrupts until interrupt handled */
+                       val = 0xFF;
+                       hdmi_writeb(val, HDMI_A_APIINTMSK);
+                       schedule_delayed_work(&(hdmi->hdcp_hdp_work), msecs_to_jiffies(50));
+               }
+       }
+
+       spin_unlock_irqrestore(&hdmi->irq_lock, flags);
+       return IRQ_HANDLED;
+}
+
+static void mxc_hdmi_setup(struct mxc_hdmi *hdmi, unsigned long event)
+{
+       struct fb_videomode m;
+       const struct fb_videomode *edid_mode;
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       fb_var_to_videomode(&m, &hdmi->fbi->var);
+       dump_fb_videomode(&m);
+
+       dev_dbg(&hdmi->pdev->dev, "%s - video mode changed\n", __func__);
+
+       /* Save mode as 'previous_mode' so that we can know if mode changed. */
+       memcpy(&hdmi->previous_mode, &m, sizeof(struct fb_videomode));
+
+       hdmi->vic = 0;
+       if (!hdmi->requesting_vga_for_initialization) {
+               /* Save mode if this isn't the result of requesting
+                * vga default. */
+               memcpy(&hdmi->previous_non_vga_mode, &m,
+                      sizeof(struct fb_videomode));
+               if (!list_empty(&hdmi->fbi->modelist)) {
+                       edid_mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist);
+                       pr_debug("edid mode ");
+                       dump_fb_videomode((struct fb_videomode *)edid_mode);
+                       hdmi->vic = mxc_edid_mode_to_vic(edid_mode);
+               }
+       }
+
+       hdmi_disable_overflow_interrupts();
+
+       dev_dbg(&hdmi->pdev->dev, "CEA mode used vic=%d\n", hdmi->vic);
+       if (hdmi->edid_cfg.hdmi_cap)
+               hdmi->hdmi_data.video_mode.mDVI = false;
+       else {
+               dev_dbg(&hdmi->pdev->dev, "CEA mode vic=%d work in DVI\n", hdmi->vic);
+               hdmi->hdmi_data.video_mode.mDVI = true;
+       }
+
+       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 = eITU601;
+       else
+               hdmi->hdmi_data.colorimetry = eITU709;
+
+       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 iface) */
+       hdmi->hdmi_data.enc_in_format = RGB;
+
+       hdmi->hdmi_data.enc_out_format = RGB;
+
+       /* YCbCr only enabled in HDMI mode */
+       if (!hdmi->hdmi_data.video_mode.mDVI &&
+               !hdmi->hdmi_data.rgb_out_enable) {
+               if (hdmi->edid_cfg.cea_ycbcr444)
+                       hdmi->hdmi_data.enc_out_format = YCBCR444;
+               else if (hdmi->edid_cfg.cea_ycbcr422)
+                       hdmi->hdmi_data.enc_out_format = YCBCR422_8BITS;
+       }
+
+       /* IPU not support depth color output */
+       hdmi->hdmi_data.enc_color_depth = 8;
+       hdmi->hdmi_data.pix_repet_factor = 0;
+       hdmi->hdmi_data.video_mode.mDataEnablePolarity = true;
+
+       /* HDMI Initialization Step B.1 */
+       hdmi_av_composer(hdmi);
+
+       /* HDMI Initializateion Step B.2 */
+       mxc_hdmi_phy_init(hdmi);
+
+       /* HDMI Initialization Step B.3 */
+       mxc_hdmi_enable_video_path(hdmi);
+
+       /* not for DVI mode */
+       if (hdmi->hdmi_data.video_mode.mDVI)
+               dev_dbg(&hdmi->pdev->dev, "%s DVI mode\n", __func__);
+       else {
+               dev_dbg(&hdmi->pdev->dev, "%s CEA mode\n", __func__);
+
+               /* HDMI Initialization Step E - Configure audio */
+               hdmi_clk_regenerator_update_pixel_clock(hdmi->fbi->var.pixclock);
+               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);
+
+       mxc_hdmi_clear_overflow(hdmi);
+
+       if (!hdmi->hdmi_data.video_mode.mDVI)
+               hdmi_enable_overflow_interrupts();
+
+       dev_dbg(&hdmi->pdev->dev, "%s exit\n\n", __func__);
+
+}
+
+/* Wait until we are registered to enable interrupts */
+static void mxc_hdmi_fb_registered(struct mxc_hdmi *hdmi)
+{
+       unsigned long flags;
+
+       if (hdmi->fb_reg)
+               return;
+
+       spin_lock_irqsave(&hdmi->irq_lock, flags);
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       hdmi_writeb(HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
+                   HDMI_PHY_I2CM_INT_ADDR);
+
+       hdmi_writeb(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((u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0);
+
+       /* Clear Hotplug interrupts */
+       hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
+
+       /* Unmute interrupts */
+       hdmi_writeb(~HDMI_IH_MUTE_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
+
+       hdmi->fb_reg = true;
+
+       spin_unlock_irqrestore(&hdmi->irq_lock, flags);
+
+}
+
+static int mxc_hdmi_fb_event(struct notifier_block *nb,
+                                       unsigned long val, void *v)
+{
+       struct fb_event *event = v;
+       struct mxc_hdmi *hdmi = container_of(nb, struct mxc_hdmi, nb);
+
+       if (strcmp(event->info->fix.id, hdmi->fbi->fix.id))
+               return 0;
+
+       switch (val) {
+       case FB_EVENT_FB_REGISTERED:
+               dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_FB_REGISTERED\n");
+               mxc_hdmi_fb_registered(hdmi);
+               hdmi_set_registered(1);
+               break;
+
+       case FB_EVENT_FB_UNREGISTERED:
+               dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_FB_UNREGISTERED\n");
+               hdmi->fb_reg = false;
+               hdmi_set_registered(0);
+               break;
+
+       case FB_EVENT_MODE_CHANGE:
+               dev_dbg(&hdmi->pdev->dev, "event=FB_EVENT_MODE_CHANGE\n");
+               if (hdmi->fb_reg)
+                       mxc_hdmi_setup(hdmi, val);
+               break;
+
+       case FB_EVENT_BLANK:
+               if ((*((int *)event->data) == FB_BLANK_UNBLANK) &&
+                       (*((int *)event->data) != hdmi->blank)) {
+                       dev_dbg(&hdmi->pdev->dev,
+                               "event=FB_EVENT_BLANK - UNBLANK\n");
+
+                       hdmi->blank = *((int *)event->data);
+
+                       if (hdmi->fb_reg && hdmi->cable_plugin)
+                               mxc_hdmi_setup(hdmi, val);
+                       hdmi_set_blank_state(1);
+
+               } else if (*((int *)event->data) != hdmi->blank) {
+                       dev_dbg(&hdmi->pdev->dev,
+                               "event=FB_EVENT_BLANK - BLANK\n");
+                       hdmi_set_blank_state(0);
+                       mxc_hdmi_abort_stream();
+
+                       mxc_hdmi_phy_disable(hdmi);
+
+                       hdmi->blank = *((int *)event->data);
+               } else
+                       dev_dbg(&hdmi->pdev->dev,
+                               "FB BLANK state no changed!\n");
+
+               break;
+
+       case FB_EVENT_SUSPEND:
+               dev_dbg(&hdmi->pdev->dev,
+                       "event=FB_EVENT_SUSPEND\n");
+
+               if (hdmi->blank == FB_BLANK_UNBLANK) {
+                       mxc_hdmi_phy_disable(hdmi);
+                       clk_disable(hdmi->hdmi_iahb_clk);
+                       clk_disable(hdmi->hdmi_isfr_clk);
+               }
+               break;
+
+       case FB_EVENT_RESUME:
+               dev_dbg(&hdmi->pdev->dev,
+                       "event=FB_EVENT_RESUME\n");
+
+               if (hdmi->blank == FB_BLANK_UNBLANK) {
+                       clk_enable(hdmi->hdmi_iahb_clk);
+                       clk_enable(hdmi->hdmi_isfr_clk);
+                       mxc_hdmi_phy_init(hdmi);
+               }
+               break;
+
+       }
+       return 0;
+}
+
+static void hdmi_init_route(struct mxc_hdmi *hdmi)
+{
+       uint32_t hdmi_mux_setting, reg;
+       int ipu_id, disp_id;
+
+       ipu_id = mxc_hdmi_ipu_id;
+       disp_id = mxc_hdmi_disp_id;
+
+       if ((ipu_id > 1) || (ipu_id < 0)) {
+               pr_err("Invalid IPU select for HDMI: %d. Set to 0\n", ipu_id);
+               ipu_id = 0;
+       }
+
+       if ((disp_id > 1) || (disp_id < 0)) {
+               pr_err("Invalid DI select for HDMI: %d. Set to 0\n", disp_id);
+               disp_id = 0;
+       }
+
+       reg = readl(hdmi->gpr_hdmi_base);
+
+       /* Configure the connection between IPU1/2 and HDMI */
+       hdmi_mux_setting = 2*ipu_id + disp_id;
+
+       /* GPR3, bits 2-3 = HDMI_MUX_CTL */
+       reg &= ~0xd;
+       reg |= hdmi_mux_setting << 2;
+
+       writel(reg, hdmi->gpr_hdmi_base);
+
+       /* Set HDMI event as SDMA event2 while Chip version later than TO1.2 */
+/*
+       if (hdmi_SDMA_check()) {
+               reg = readl(hdmi->gpr_sdma_base);
+               reg |= 0x1;
+               writel(reg, hdmi->gpr_sdma_base);
+       }
+*/
+}
+
+static void hdmi_get_of_property(struct mxc_hdmi *hdmi)
+{
+       struct platform_device *pdev = hdmi->pdev;
+       struct device_node *np = pdev->dev.of_node;
+       const struct of_device_id *of_id =
+                       of_match_device(imx_hdmi_dt_ids, &pdev->dev);
+       int ret;
+       u32 phy_reg_vlev = 0, phy_reg_cksymtx = 0;
+
+       if (of_id) {
+               pdev->id_entry = of_id->data;
+               hdmi->cpu_type = pdev->id_entry->driver_data;
+       }
+
+       /* HDMI PHY register vlev and cksymtx preperty is optional.
+        * It is for specific board to pass HCT electrical part.
+        * Default value will been setting in HDMI PHY config function
+        * if it is not define in device tree.
+        */
+       ret = of_property_read_u32(np, "phy_reg_vlev", &phy_reg_vlev);
+       if (ret)
+               dev_dbg(&pdev->dev, "No board specific HDMI PHY vlev\n");
+
+       ret = of_property_read_u32(np, "phy_reg_cksymtx", &phy_reg_cksymtx);
+       if (ret)
+               dev_dbg(&pdev->dev, "No board specific HDMI PHY cksymtx\n");
+
+       /* Specific phy config */
+       hdmi->phy_config.reg_cksymtx = phy_reg_cksymtx;
+       hdmi->phy_config.reg_vlev = phy_reg_vlev;
+
+}
+
+/* HDMI Initialization Step A */
+static int mxc_hdmi_disp_init(struct mxc_dispdrv_handle *disp,
+                             struct mxc_dispdrv_setting *setting)
+{
+       int ret = 0;
+       u32 i;
+       const struct fb_videomode *mode;
+       struct fb_videomode m;
+       struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
+       int irq = platform_get_irq(hdmi->pdev, 0);
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       /* Check hdmi disp init once */
+       if (hdmi_inited) {
+               dev_err(&hdmi->pdev->dev,
+                               "Error only one HDMI output support now!\n");
+               return -1;
+       }
+
+       hdmi_get_of_property(hdmi);
+
+       if (irq < 0)
+               return -ENODEV;
+
+       hdmi->dft_mode_set = false;
+
+       /* Setting HDMI default to blank state */
+       hdmi->blank = FB_BLANK_POWERDOWN;
+
+       setting->dev_id = mxc_hdmi_ipu_id;
+       setting->disp_id = mxc_hdmi_disp_id;
+       setting->if_fmt = IPU_PIX_FMT_RGB24;
+
+       hdmi->dft_mode_str = setting->dft_mode_str;
+       hdmi->default_bpp = setting->default_bpp;
+       dev_dbg(&hdmi->pdev->dev, "%s - default mode %s bpp=%d\n",
+               __func__, hdmi->dft_mode_str, hdmi->default_bpp);
+
+       hdmi->fbi = setting->fbi;
+
+       hdmi_init_route(hdmi);
+
+       hdmi->hdmi_isfr_clk = clk_get(&hdmi->pdev->dev, "hdmi_isfr");
+       if (IS_ERR(hdmi->hdmi_isfr_clk)) {
+               ret = PTR_ERR(hdmi->hdmi_isfr_clk);
+               dev_err(&hdmi->pdev->dev,
+                       "Unable to get HDMI clk: %d\n", ret);
+               goto egetclk1;
+       }
+
+       ret = clk_prepare_enable(hdmi->hdmi_isfr_clk);
+       if (ret < 0) {
+               dev_err(&hdmi->pdev->dev,
+                       "Cannot enable HDMI isfr clock: %d\n", ret);
+               goto erate1;
+       }
+
+       hdmi->hdmi_iahb_clk = clk_get(&hdmi->pdev->dev, "hdmi_iahb");
+       if (IS_ERR(hdmi->hdmi_iahb_clk)) {
+               ret = PTR_ERR(hdmi->hdmi_iahb_clk);
+               dev_err(&hdmi->pdev->dev,
+                       "Unable to get HDMI clk: %d\n", ret);
+               goto egetclk2;
+       }
+
+       ret = clk_prepare_enable(hdmi->hdmi_iahb_clk);
+       if (ret < 0) {
+               dev_err(&hdmi->pdev->dev,
+                       "Cannot enable HDMI iahb clock: %d\n", ret);
+               goto erate2;
+       }
+
+       dev_dbg(&hdmi->pdev->dev, "Enabled HDMI clocks\n");
+
+       /* Init DDC pins for HDCP  */
+       if (hdcp_init) {
+               hdmi->pinctrl = devm_pinctrl_get_select_default(&hdmi->pdev->dev);
+               if (IS_ERR(hdmi->pinctrl)) {
+                       dev_err(&hdmi->pdev->dev, "can't get/select DDC pinctrl\n");
+                       goto erate2;
+               }
+       }
+
+       /* Product and revision IDs */
+       dev_info(&hdmi->pdev->dev,
+               "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
+               hdmi_readb(HDMI_DESIGN_ID),
+               hdmi_readb(HDMI_REVISION_ID),
+               hdmi_readb(HDMI_PRODUCT_ID0),
+               hdmi_readb(HDMI_PRODUCT_ID1));
+
+       /* To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
+        * N and cts values before enabling phy */
+       hdmi_init_clk_regenerator();
+
+       INIT_LIST_HEAD(&hdmi->fbi->modelist);
+
+       spin_lock_init(&hdmi->irq_lock);
+
+       /* Set the default mode and modelist when disp init. */
+       fb_find_mode(&hdmi->fbi->var, hdmi->fbi,
+                    hdmi->dft_mode_str, NULL, 0, NULL,
+                    hdmi->default_bpp);
+
+       console_lock();
+
+       fb_destroy_modelist(&hdmi->fbi->modelist);
+
+       /*Add all no interlaced CEA mode to default modelist */
+       for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
+               mode = &mxc_cea_mode[i];
+               if (!(mode->vmode & FB_VMODE_INTERLACED) && (mode->xres != 0))
+                       fb_add_videomode(mode, &hdmi->fbi->modelist);
+       }
+
+       /*Add XGA and SXGA to default modelist */
+       fb_add_videomode(&xga_mode, &hdmi->fbi->modelist);
+       fb_add_videomode(&sxga_mode, &hdmi->fbi->modelist);
+
+       console_unlock();
+
+       /* Find a nearest mode in default modelist */
+       fb_var_to_videomode(&m, &hdmi->fbi->var);
+       dump_fb_videomode(&m);
+
+       mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist);
+       if (!mode) {
+               pr_err("%s: could not find mode in modelist\n", __func__);
+               return -1;
+       }
+
+       fb_videomode_to_var(&hdmi->fbi->var, mode);
+
+       /* Default setting HDMI working in HDMI mode*/
+       hdmi->edid_cfg.hdmi_cap = true;
+
+       INIT_DELAYED_WORK(&hdmi->hotplug_work, hotplug_worker);
+       INIT_DELAYED_WORK(&hdmi->hdcp_hdp_work, hdcp_hdp_worker);
+
+       /* Configure registers related to HDMI interrupt
+        * generation before registering IRQ. */
+       hdmi_writeb(HDMI_PHY_HPD, HDMI_PHY_POL0);
+
+       /* Clear Hotplug interrupts */
+       hdmi_writeb(HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
+
+       hdmi->nb.notifier_call = mxc_hdmi_fb_event;
+       ret = fb_register_client(&hdmi->nb);
+       if (ret < 0)
+               goto efbclient;
+
+       memset(&hdmi->hdmi_data, 0, sizeof(struct hdmi_data_info));
+
+       /* Default HDMI working in RGB mode */
+       hdmi->hdmi_data.rgb_out_enable = true;
+
+       ret = devm_request_irq(&hdmi->pdev->dev, irq, mxc_hdmi_hotplug, IRQF_SHARED,
+                       dev_name(&hdmi->pdev->dev), hdmi);
+       if (ret < 0) {
+               dev_err(&hdmi->pdev->dev,
+                       "Unable to request irq: %d\n", ret);
+               goto ereqirq;
+       }
+
+       ret = device_create_file(&hdmi->pdev->dev, &dev_attr_fb_name);
+       if (ret < 0)
+               dev_warn(&hdmi->pdev->dev,
+                       "cound not create sys node for fb name\n");
+       ret = device_create_file(&hdmi->pdev->dev, &dev_attr_cable_state);
+       if (ret < 0)
+               dev_warn(&hdmi->pdev->dev,
+                       "cound not create sys node for cable state\n");
+       ret = device_create_file(&hdmi->pdev->dev, &dev_attr_edid);
+       if (ret < 0)
+               dev_warn(&hdmi->pdev->dev,
+                       "cound not create sys node for edid\n");
+
+       ret = device_create_file(&hdmi->pdev->dev, &dev_attr_rgb_out_enable);
+       if (ret < 0)
+               dev_warn(&hdmi->pdev->dev,
+                       "cound not create sys node for rgb out enable\n");
+
+       ret = device_create_file(&hdmi->pdev->dev, &dev_attr_hdcp_enable);
+       if (ret < 0)
+               dev_warn(&hdmi->pdev->dev,
+                       "cound not create sys node for hdcp enable\n");
+
+       dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
+
+       hdmi_inited = true;
+
+       return ret;
+
+efbclient:
+       free_irq(irq, hdmi);
+ereqirq:
+       clk_disable_unprepare(hdmi->hdmi_iahb_clk);
+erate2:
+       clk_put(hdmi->hdmi_iahb_clk);
+egetclk2:
+       clk_disable_unprepare(hdmi->hdmi_isfr_clk);
+erate1:
+       clk_put(hdmi->hdmi_isfr_clk);
+egetclk1:
+       dev_dbg(&hdmi->pdev->dev, "%s error exit\n", __func__);
+
+       return ret;
+}
+
+static void mxc_hdmi_disp_deinit(struct mxc_dispdrv_handle *disp)
+{
+       struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
+
+       dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+
+       fb_unregister_client(&hdmi->nb);
+
+       clk_disable_unprepare(hdmi->hdmi_isfr_clk);
+       clk_put(hdmi->hdmi_isfr_clk);
+       clk_disable_unprepare(hdmi->hdmi_iahb_clk);
+       clk_put(hdmi->hdmi_iahb_clk);
+
+       platform_device_unregister(hdmi->pdev);
+
+       hdmi_inited = false;
+}
+
+static struct mxc_dispdrv_driver mxc_hdmi_drv = {
+       .name   = DISPDRV_HDMI,
+       .init   = mxc_hdmi_disp_init,
+       .deinit = mxc_hdmi_disp_deinit,
+       .enable = mxc_hdmi_power_on,
+       .disable = mxc_hdmi_power_off,
+};
+
+
+static int mxc_hdmi_open(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+
+static long mxc_hdmi_ioctl(struct file *file,
+               unsigned int cmd, unsigned long arg)
+{
+       int __user *argp = (void __user *)arg;
+       int ret = 0;
+
+       switch (cmd) {
+       case HDMI_IOC_GET_RESOURCE:
+               ret = copy_to_user(argp, &g_hdmi->hdmi_data,
+                               sizeof(g_hdmi->hdmi_data)) ? -EFAULT : 0;
+               break;
+       case HDMI_IOC_GET_CPU_TYPE:
+               *argp = g_hdmi->cpu_type;
+               break;
+       default:
+               pr_debug("Unsupport cmd %d\n", cmd);
+               break;
+     }
+     return ret;
+}
+
+static int mxc_hdmi_release(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+
+static const struct file_operations mxc_hdmi_fops = {
+       .owner = THIS_MODULE,
+       .open = mxc_hdmi_open,
+       .release = mxc_hdmi_release,
+       .unlocked_ioctl = mxc_hdmi_ioctl,
+};
+
+
+static int mxc_hdmi_probe(struct platform_device *pdev)
+{
+       struct mxc_hdmi *hdmi;
+       struct device *temp_class;
+       struct resource *res;
+       int ret = 0;
+
+       /* Check that I2C driver is loaded and available */
+       /* Skip I2C driver available check when HDCP enable */
+       if (!hdmi_i2c && !hdcp_init)
+               return -ENODEV;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res)
+               return -ENOENT;
+
+       hdmi = devm_kzalloc(&pdev->dev,
+                               sizeof(struct mxc_hdmi),
+                               GFP_KERNEL);
+       if (!hdmi) {
+               dev_err(&pdev->dev, "Cannot allocate device data\n");
+               ret = -ENOMEM;
+               goto ealloc;
+       }
+       g_hdmi = hdmi;
+
+       hdmi_major = register_chrdev(hdmi_major, "mxc_hdmi", &mxc_hdmi_fops);
+       if (hdmi_major < 0) {
+               printk(KERN_ERR "HDMI: unable to get a major for HDMI\n");
+               ret = -EBUSY;
+               goto ealloc;
+       }
+
+       hdmi_class = class_create(THIS_MODULE, "mxc_hdmi");
+       if (IS_ERR(hdmi_class)) {
+               ret = PTR_ERR(hdmi_class);
+               goto err_out_chrdev;
+       }
+
+       temp_class = device_create(hdmi_class, NULL, MKDEV(hdmi_major, 0),
+                                  NULL, "mxc_hdmi");
+       if (IS_ERR(temp_class)) {
+               ret = PTR_ERR(temp_class);
+               goto err_out_class;
+       }
+
+       hdmi->pdev = pdev;
+
+       hdmi->core_pdev = platform_device_alloc("mxc_hdmi_core", -1);
+       if (!hdmi->core_pdev) {
+               pr_err("%s failed platform_device_alloc for hdmi core\n",
+                       __func__);
+               ret = -ENOMEM;
+               goto ecore;
+       }
+
+       hdmi->gpr_base = ioremap(res->start, resource_size(res));
+       if (!hdmi->gpr_base) {
+               dev_err(&pdev->dev, "ioremap failed\n");
+               ret = -ENOMEM;
+               goto eiomap;
+       }
+
+       hdmi->gpr_hdmi_base = hdmi->gpr_base + 3;
+       hdmi->gpr_sdma_base = hdmi->gpr_base;
+
+       hdmi_inited = false;
+
+       hdmi->disp_mxc_hdmi = mxc_dispdrv_register(&mxc_hdmi_drv);
+       if (IS_ERR(hdmi->disp_mxc_hdmi)) {
+               dev_err(&pdev->dev, "Failed to register dispdrv - 0x%x\n",
+                       (int)hdmi->disp_mxc_hdmi);
+               ret = (int)hdmi->disp_mxc_hdmi;
+               goto edispdrv;
+       }
+       mxc_dispdrv_setdata(hdmi->disp_mxc_hdmi, hdmi);
+
+       platform_set_drvdata(pdev, hdmi);
+
+       return 0;
+edispdrv:
+       iounmap(hdmi->gpr_base);
+eiomap:
+       platform_device_put(hdmi->core_pdev);
+ecore:
+       kfree(hdmi);
+err_out_class:
+       device_destroy(hdmi_class, MKDEV(hdmi_major, 0));
+       class_destroy(hdmi_class);
+err_out_chrdev:
+       unregister_chrdev(hdmi_major, "mxc_hdmi");
+ealloc:
+       return ret;
+}
+
+static int mxc_hdmi_remove(struct platform_device *pdev)
+{
+       struct mxc_hdmi *hdmi = platform_get_drvdata(pdev);
+       int irq = platform_get_irq(pdev, 0);
+
+       fb_unregister_client(&hdmi->nb);
+
+       mxc_dispdrv_puthandle(hdmi->disp_mxc_hdmi);
+       mxc_dispdrv_unregister(hdmi->disp_mxc_hdmi);
+       iounmap(hdmi->gpr_base);
+       /* No new work will be scheduled, wait for running ISR */
+       free_irq(irq, hdmi);
+       kfree(hdmi);
+       g_hdmi = NULL;
+
+       return 0;
+}
+
+static struct platform_driver mxc_hdmi_driver = {
+       .probe = mxc_hdmi_probe,
+       .remove = mxc_hdmi_remove,
+       .driver = {
+               .name = "mxc_hdmi",
+               .of_match_table = imx_hdmi_dt_ids,
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init mxc_hdmi_init(void)
+{
+       return platform_driver_register(&mxc_hdmi_driver);
+}
+module_init(mxc_hdmi_init);
+
+static void __exit mxc_hdmi_exit(void)
+{
+       if (hdmi_major > 0) {
+               device_destroy(hdmi_class, MKDEV(hdmi_major, 0));
+               class_destroy(hdmi_class);
+               unregister_chrdev(hdmi_major, "mxc_hdmi");
+               hdmi_major = 0;
+       }
+
+       platform_driver_unregister(&mxc_hdmi_driver);
+}
+module_exit(mxc_hdmi_exit);
+
+static int mxc_hdmi_i2c_probe(struct i2c_client *client,
+               const struct i2c_device_id *id)
+{
+       if (!i2c_check_functionality(client->adapter,
+                               I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
+               return -ENODEV;
+
+       hdmi_i2c = client;
+
+       return 0;
+}
+
+static int mxc_hdmi_i2c_remove(struct i2c_client *client)
+{
+       hdmi_i2c = NULL;
+       return 0;
+}
+
+static const struct of_device_id imx_hdmi_i2c_match[] = {
+       { .compatible = "fsl,imx6-hdmi-i2c", },
+       { /* sentinel */ }
+};
+
+static const struct i2c_device_id mxc_hdmi_i2c_id[] = {
+       { "mxc_hdmi_i2c", 0 },
+       {},
+};
+MODULE_DEVICE_TABLE(i2c, mxc_hdmi_i2c_id);
+
+static struct i2c_driver mxc_hdmi_i2c_driver = {
+       .driver = {
+                  .name = "mxc_hdmi_i2c",
+                       .of_match_table = imx_hdmi_i2c_match,
+                  },
+       .probe = mxc_hdmi_i2c_probe,
+       .remove = mxc_hdmi_i2c_remove,
+       .id_table = mxc_hdmi_i2c_id,
+};
+
+static int __init mxc_hdmi_i2c_init(void)
+{
+       return i2c_add_driver(&mxc_hdmi_i2c_driver);
+}
+
+static void __exit mxc_hdmi_i2c_exit(void)
+{
+       i2c_del_driver(&mxc_hdmi_i2c_driver);
+}
+
+module_init(mxc_hdmi_i2c_init);
+module_exit(mxc_hdmi_i2c_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
diff --git a/include/linux/mfd/mxc-hdmi-core.h b/include/linux/mfd/mxc-hdmi-core.h
new file mode 100644 (file)
index 0000000..f552498
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+#ifndef __LINUX_MXC_HDMI_CORE_H_
+#define __LINUX_MXC_HDMI_CORE_H_
+
+#include <video/mxc_edid.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#define IRQ_DISABLE_SUCCEED    0
+#define IRQ_DISABLE_FAIL       1
+
+bool hdmi_check_overflow(void);
+
+u8 hdmi_readb(unsigned int reg);
+void hdmi_writeb(u8 value, unsigned int reg);
+void hdmi_mask_writeb(u8 data, unsigned int addr, u8 shift, u8 mask);
+unsigned int hdmi_read4(unsigned int reg);
+void hdmi_write4(unsigned int value, unsigned int reg);
+
+void hdmi_irq_init(void);
+void hdmi_irq_enable(int irq);
+unsigned int hdmi_irq_disable(int irq);
+
+void hdmi_set_sample_rate(unsigned int rate);
+void hdmi_set_dma_mode(unsigned int dma_running);
+void hdmi_init_clk_regenerator(void);
+void hdmi_clk_regenerator_update_pixel_clock(u32 pixclock);
+
+void hdmi_set_edid_cfg(struct mxc_edid_cfg *cfg);
+void hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg);
+
+extern int mxc_hdmi_ipu_id;
+extern int mxc_hdmi_disp_id;
+
+void hdmi_set_registered(int registered);
+int hdmi_get_registered(void);
+unsigned int hdmi_SDMA_check(void);
+int mxc_hdmi_abort_stream(void);
+int mxc_hdmi_register_audio(struct snd_pcm_substream *substream);
+void mxc_hdmi_unregister_audio(struct snd_pcm_substream *substream);
+unsigned int hdmi_set_cable_state(unsigned int state);
+unsigned int hdmi_set_blank_state(unsigned int state);
+int check_hdmi_state(void);
+
+#endif
diff --git a/include/video/mxc_edid.h b/include/video/mxc_edid.h
new file mode 100755 (executable)
index 0000000..34e797c
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2009-2013 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup Framebuffer Framebuffer Driver for SDC and ADC.
+ */
+
+/*!
+ * @file mxc_edid.h
+ *
+ * @brief MXC EDID tools
+ *
+ * @ingroup Framebuffer
+ */
+
+#ifndef MXC_EDID_H
+#define MXC_EDID_H
+
+#include <linux/fb.h>
+
+#define FB_VMODE_ASPECT_4_3    0x10
+#define FB_VMODE_ASPECT_16_9   0x20
+#define FB_VMODE_ASPECT_MASK   (FB_VMODE_ASPECT_4_3 | FB_VMODE_ASPECT_16_9)
+
+enum cea_audio_coding_types {
+       AUDIO_CODING_TYPE_REF_STREAM_HEADER     =  0,
+       AUDIO_CODING_TYPE_LPCM                  =  1,
+       AUDIO_CODING_TYPE_AC3                   =  2,
+       AUDIO_CODING_TYPE_MPEG1                 =  3,
+       AUDIO_CODING_TYPE_MP3                   =  4,
+       AUDIO_CODING_TYPE_MPEG2                 =  5,
+       AUDIO_CODING_TYPE_AACLC                 =  6,
+       AUDIO_CODING_TYPE_DTS                   =  7,
+       AUDIO_CODING_TYPE_ATRAC                 =  8,
+       AUDIO_CODING_TYPE_SACD                  =  9,
+       AUDIO_CODING_TYPE_EAC3                  = 10,
+       AUDIO_CODING_TYPE_DTS_HD                = 11,
+       AUDIO_CODING_TYPE_MLP                   = 12,
+       AUDIO_CODING_TYPE_DST                   = 13,
+       AUDIO_CODING_TYPE_WMAPRO                = 14,
+       AUDIO_CODING_TYPE_RESERVED              = 15,
+};
+
+struct mxc_hdmi_3d_format {
+       unsigned char vic_order_2d;
+       unsigned char struct_3d;
+       unsigned char detail_3d;
+       unsigned char reserved;
+};
+
+struct mxc_edid_cfg {
+       bool cea_underscan;
+       bool cea_basicaudio;
+       bool cea_ycbcr444;
+       bool cea_ycbcr422;
+       bool hdmi_cap;
+
+       /*VSD*/
+       bool vsd_support_ai;
+       bool vsd_dc_48bit;
+       bool vsd_dc_36bit;
+       bool vsd_dc_30bit;
+       bool vsd_dc_y444;
+       bool vsd_dvi_dual;
+
+       bool vsd_cnc0;
+       bool vsd_cnc1;
+       bool vsd_cnc2;
+       bool vsd_cnc3;
+
+       u8 vsd_video_latency;
+       u8 vsd_audio_latency;
+       u8 vsd_I_video_latency;
+       u8 vsd_I_audio_latency;
+
+       u8 physical_address[4];
+       u8 hdmi_vic[64];
+       struct mxc_hdmi_3d_format hdmi_3d_format[64];
+       u16 hdmi_3d_mask_all;
+       u16 hdmi_3d_struct_all;
+       u32 vsd_max_tmdsclk_rate;
+
+       u8 max_channels;
+       u8 sample_sizes;
+       u8 sample_rates;
+       u8 speaker_alloc;
+};
+
+int mxc_edid_var_to_vic(struct fb_var_screeninfo *var);
+int mxc_edid_mode_to_vic(const struct fb_videomode *mode);
+int mxc_edid_read(struct i2c_adapter *adp, unsigned short addr,
+       unsigned char *edid, struct mxc_edid_cfg *cfg, struct fb_info *fbi);
+int mxc_edid_parse_ext_blk(unsigned char *edid, struct mxc_edid_cfg *cfg,
+       struct fb_monspecs *specs);
+#endif
diff --git a/include/video/mxc_hdmi.h b/include/video/mxc_hdmi.h
new file mode 100644 (file)
index 0000000..94f7638
--- /dev/null
@@ -0,0 +1,1095 @@
+/*
+ * 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.
+ *
+ * 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.
+ */
+
+#ifndef __MXC_HDMI_H__
+#define __MXC_HDMI_H__
+
+/*
+ * Hdmi controller registers
+ */
+
+/* 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_I2CM_ADDRESS                       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
+
+/* Random Number Generator Registers (RNG) */
+#define HDMI_RNG_BASE                           0x8000
+
+
+/*
+ * Register field definitions
+ */
+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_CEC_STAT0 field values */
+       HDMI_IH_CEC_STAT0_WAKEUP = 0x40,
+       HDMI_IH_CEC_STAT0_ERROR_FOLL = 0x20,
+       HDMI_IH_CEC_STAT0_ERROR_INIT = 0x10,
+       HDMI_IH_CEC_STAT0_ARB_LOST = 0x8,
+       HDMI_IH_CEC_STAT0_NACK = 0x4,
+       HDMI_IH_CEC_STAT0_EOM = 0x2,
+       HDMI_IH_CEC_STAT0_DONE = 0x1,
+
+
+/* IH_MUTE_I2CMPHY_STAT0 field values */
+       HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYDONE = 0x2,
+       HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYERROR = 0x1,
+
+/* IH_PHY_STAT0 field values */
+       HDMI_IH_MUTE_PHY_STAT0_RX_SENSE3 = 0x20,
+       HDMI_IH_MUTE_PHY_STAT0_RX_SENSE2 = 0x10,
+       HDMI_IH_MUTE_PHY_STAT0_RX_SENSE1 = 0x8,
+       HDMI_IH_MUTE_PHY_STAT0_RX_SENSE0 = 0x4,
+       HDMI_IH_MUTE_PHY_STAT0_TX_PHY_LOCK = 0x2,
+       HDMI_IH_MUTE_PHY_STAT0_HPD = 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 field 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,
+
+
+/* I2CM_OPERATION field values */
+       HDMI_I2CM_OPERATION_WRITE = 0x10,
+       HDMI_I2CM_OPERATION_READ_EXT = 0x2,
+       HDMI_I2CM_OPERATION_READ = 0x1,
+
+/* HDMI_I2CM_INT */
+       HDMI_I2CM_INT_DONE_POL = 0x08,
+       HDMI_I2CM_INT_DONE_MASK = 0x04,
+
+/* HDMI_I2CM_CTLINT */
+       HDMI_I2CM_CTLINT_NAC_POL = 0x80,
+       HDMI_I2CM_CTLINT_NAC_MASK = 0x40,
+       HDMI_I2CM_CTLINT_ARBITRATION_POL = 0x08,
+       HDMI_I2CM_CTLINT_ARBITRATION_MASK = 0x04,
+
+};
+
+/* IOCTL commands */
+#define HDMI_IOC_MAGIC  'H'
+
+#define HDMI_IOC_GET_RESOURCE  _IO(HDMI_IOC_MAGIC, 0)
+#define HDMI_IOC_GET_CPU_TYPE  _IO(HDMI_IOC_MAGIC, 1)
+
+
+#endif /* __MXC_HDMI_H__ */