Addition of the OTM HDMI driver for Medfield.
authorArun Kannan <arun.kannan@intel.com>
Mon, 30 Jan 2012 22:17:14 +0000 (00:17 +0200)
committerMarkus Lehtonen <markus.lehtonen@linux.intel.com>
Tue, 3 Jul 2012 09:29:37 +0000 (12:29 +0300)
This is a modular, reusable driver for HDMI used across platforms.
This driver has already achieved HDMI certification on the Greenridge platform,
and was also reused on the Medfield honeycomb stack.

Signed-off-by: Arun Kannan <arun.kannan@intel.com>
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
36 files changed:
drivers/staging/mrst/Kconfig
drivers/staging/mrst/drv/otm_hdmi/Makefile [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/ipil/common/ipil_hdcp.c [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/ipil/common/ipil_internal.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/ipil/common/otm_ipil_main.c [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/ipil/include/hdcp_rx_defs.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/ipil/include/hdmi_hal.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/ipil/include/ipil_hdcp_api.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/ipil/include/ipil_hdmi.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/ipil/specific/include/ips_hdcp_api.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/ipil/specific/include/ips_hdmi.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/ipil/specific/mfld/ips_hdcp.c [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/ipil/specific/mfld/ips_hdmi.c [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/ipil/specific/mfld/mfld_hdcp_reg.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/ipil/specific/mfld/mfld_hdmi_reg.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/ipil/specific/mfld/mfld_utils.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/os/android/android_hdmi.c [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/os/android/include/android_hdmi.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/common/edid.c [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/common/edid.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/common/edid_internal.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/common/edid_print.c [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/common/hdcp.c [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/common/hdmi_internal.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/common/hdmi_timings.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/common/infoframes.c [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/common/infoframes_api.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/common/mode_info.c [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/common/otm_hdmi.c [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/include/hdcp_api.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/include/otm_hdmi.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/include/otm_hdmi_defs.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/include/otm_hdmi_types.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/specific/include/ps_hdmi.h [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/specific/mfld/ps_hdmi.c [new file with mode: 0644]
drivers/staging/mrst/drv/otm_hdmi/pil/specific/mfld/ps_hdmi_tablet.c [new file with mode: 0644]

index 41ca4ab..e61f0a2 100644 (file)
@@ -88,6 +88,31 @@ config MDFD_HDMI
         help
           xxxxxx
 
+choice
+         prompt "HDMI board support"
+         depends on MDFD_HDMI
+         default MDFD_HDMI_REDRIDGE
+
+config MDFD_HDMI_GREENRIDGE
+         bool "Greenridge HDMI support"
+         depends on MDFD_HDMI
+         help
+           HDMI support for Greenridge.
+
+config MDFD_HDMI_REDRIDGE
+         bool "Red Ridge HDMI support"
+         depends on MDFD_HDMI
+         help
+           HDMI support for Red Ridge.
+
+config MDFD_HDMI_PR2
+         bool "PR2 HDMI support"
+         depends on MDFD_HDMI
+         help
+           HDMI support for PR2.
+
+endchoice
+
 config MDFD_GL3
        bool "Enable GL3 Cache for GUNIT"
        depends on DRM_MDFLD
diff --git a/drivers/staging/mrst/drv/otm_hdmi/Makefile b/drivers/staging/mrst/drv/otm_hdmi/Makefile
new file mode 100644 (file)
index 0000000..24ac818
--- /dev/null
@@ -0,0 +1,242 @@
+########################################################################
+#
+# This file is provided under a dual BSD/GPLv2 license.  When using or
+# redistributing this file, you may do so under either license.
+#
+# GPL LICENSE SUMMARY
+#
+# Copyright(c) 2011 Intel Corporation. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# 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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+# The full GNU General Public License is included in this distribution
+# in the file called LICENSE.GPL.
+#
+# Contact Information:
+# Intel Corporation
+# 2200 Mission College Blvd.
+# Santa Clara, CA  97052
+#
+# BSD LICENSE
+#
+# Copyright(c) 2011 Intel Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+#   * Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#   * Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in
+#     the documentation and/or other materials provided with the
+#     distribution.
+#   * Neither the name of Intel Corporation nor the names of its
+#     contributors may be used to endorse or promote products derived
+#     from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+########################################################################
+
+DISP_ROOT=$(CURDIR)
+
+TARGET = otm_hdmi
+
+INCDIR = drivers/staging/mrst/
+OTM_HDMI_INCDIR = $(INCDIR)/drv/otm_hdmi
+
+include_dirs := \
+        -I$(INCDIR)/pvr/include4 \
+        -I$(INCDIR)/pvr/services4/include \
+        -I$(INCDIR)/pvr/services4/include/env/linux \
+        -I$(INCDIR)/pvr/services4/srvkm/env/linux \
+        -I$(INCDIR)/pvr/services4/srvkm/include \
+        -I$(INCDIR)/pvr/services4/srvkm/bridged \
+        -I$(INCDIR)/pvr/services4/system/include \
+        -I$(INCDIR)/pvr/services4/srvkm/hwdefs \
+        -I$(INCDIR)/pvr/services4/srvkm/bridged/sgx \
+        -I$(INCDIR)/pvr/services4/srvkm/devices/sgx \
+        -I$(INCDIR)/pvr/services4/srvkm/common \
+        -I$(INCDIR)/pvr/services4/3rdparty/linux_framebuffer_drm \
+        -I$(INCDIR)/ \
+        -I$(INCDIR)/drv \
+        -I$(INCDIR)/bc_video \
+        -I$(INCDIR)/imgv \
+        -Iinclude/linux \
+        -Iinclude/drm \
+       -I$(OTM_HDMI_INCDIR)/os/include \
+       -I$(OTM_HDMI_INCDIR)/os/android/include \
+       -I$(OTM_HDMI_INCDIR)/pil/include \
+       -I$(OTM_HDMI_INCDIR)/pil/common \
+       -I$(OTM_HDMI_INCDIR)/pil/specific/include \
+       -I$(OTM_HDMI_INCDIR)/ipil/include \
+       -I$(OTM_HDMI_INCDIR)/ipil/common \
+       -I$(OTM_HDMI_INCDIR)/ipil/specific/include \
+
+ccflags-y += $(include_dirs)
+ifeq ($(CONFIG_MDFD_HDMI_GREENRIDGE),y)
+   ccflags-y += -I$(INCDIR)/pvr/services4/system/intel_drm -DSGX535 -DSUPPORT_SGX535 -DSGX_CORE_REV=121 -DANDROID -D_linux_ -D__KERNEL__ -DMRST
+else ifeq ($(CONFIG_MDFD_HDMI_REDRIDGE),y)
+   ccflags-y += -I$(INCDIR)/pvr/services4/system/intel_drm -I$(INCDIR)/pvr/services4/system/unified -DSGX540 -DSUPPORT_SGX540 -DSGX_CORE_REV=121 -DANDROID -D_linux_ -D__KERNEL__
+else ifeq ($(CONFIG_MDFD_HDMI_PR2),y)
+   ccflags-y += -I$(INCDIR)/pvr/services4/system/intel_drm -DSGX540 -DSUPPORT_SGX540 -DSGX_CORE_REV=121 -DANDROID -D_linux_ -D__KERNEL__
+endif
+
+ccflags-y += \
+        -DLINUX \
+    -DPVRSRV_MODNAME="\"pvrsrvkm\""
+ifeq ($(CONFIG_MDFD_HDMI_GREENRIDGE),y)
+ccflags-y += \
+       -DPVR_BUILD_DIR="\"pc_i686_moorestown_linux\""
+endif
+ifeq ($(CONFIG_MDFD_HDMI_REDRIDGE),y)
+ccflags-y += \
+        -DPVR_BUILD_DIR="\"pc_i686_medfield_linux\"" \
+       -DMFLD_HDMI_DV1 \
+       -UOTM_HDMI_HDCP_ENABLE # enable HDCP by defining this flag
+endif
+ifeq ($(CONFIG_MDFD_HDMI_PR2),y)
+ccflags-y += \
+        -DPVR_BUILD_DIR="\"pc_i686_medfield_linux\"" \
+       -DMFLD_HDMI_PR3 \
+       -UOTM_HDMI_HDCP_ENABLE # enable HDCP by defining this flag
+endif
+ccflags-y += \
+        -DPVR_LINUX_MISR_USING_WORKQUEUE \
+        -DSERVICES4 \
+        -D_XOPEN_SOURCE=600 \
+        -DPVR2D_VALIDATE_INPUT_PARAMS \
+        -DDISPLAY_CONTROLLER=mrstlfb \
+        -UDEBUG_LOG_PATH_TRUNCATE \
+        -DSUPPORT_LIBDRM_LITE \
+        -DOPK_FALLBACK="" \
+        -DSUPPORT_ANDROID_PLATFORM \
+        -DPROFILE_COMM \
+    -DSUPPORT_ANDROID_PLATFORM \
+        -DSUPPORT_GRAPHICS_HAL \
+        -DPVR_SECURE_FD_EXPORT \
+        -DSUPPORT_SRVINIT \
+        -DSUPPORT_SGX \
+        -DSUPPORT_PERCONTEXT_PB \
+        -DSUPPORT_LINUX_X86_WRITECOMBINE \
+        -DTRANSFER_QUEUE \
+        -DSUPPORT_DRI_DRM \
+        -DSUPPORT_DRI_DRM_EXT \
+    -DSUPPORT_DRI_DRM_NO_DROPMASTER \
+        -DSYS_USING_INTERRUPTS \
+        -DSUPPORT_HW_RECOVERY \
+        -DSUPPORT_ACTIVE_POWER_MANAGEMENT \
+        -DPVR_SECURE_HANDLES \
+        -DLDM_PCI \
+        -DUSE_PTHREADS \
+        -DSUPPORT_SGX_EVENT_OBJECT \
+        -DSUPPORT_SGX_HWPERF \
+        -DSUPPORT_SGX_LOW_LATENCY_SCHEDULING \
+        -DSUPPORT_LINUX_X86_PAT \
+        -DPVR_PROC_USE_SEQ_FILE \
+        -DSUPPORT_CPU_CACHED_BUFFERS \
+    -DDRM_PVR_RESERVED_INTEL_ORDER \
+    -DDRM_PVR_USE_INTEL_FB \
+        -DSUPPORT_MEMINFO_IDS \
+    -DSUPPORT_SGX_NEW_STATUS_VALS
+
+ccflags-$(CONFIG_DRM_MID_RELEASE) += -DBUILD="\"release\"" -DPVR_BUILD_TYPE="\"release\"" -DRELEASE
+ccflags-$(CONFIG_DRM_MID_DEBUG) += -DBUILD="\"debug\"" -DPVR_BUILD_TYPE="\"debug\"" -DDEBUG -DDEBUG_LINUX_MEM_AREAS -DDEBUG_LINUX_MEMORY_ALLOCATIONS -DDEBUG_LINUX_MMAP_AREAS -DDEBUG_BRIDGE_KM
+ccflags-$(CONFIG_PCI_MSI) += -DCONFIG_PCI_MSI
+
+ifeq ($(CONFIG_MDFD_HDMI_REDRIDGE),y)
+   GL3_EXTERNAL_SYSTEM_CACHE ?=1
+   ifeq ($(GL3_EXTERNAL_SYSTEM_CACHE),1)
+      SUPPORT_EXTERNAL_SYSTEM_CACHE = y
+      CONFIG_MDFD_GL3 = y
+   else
+      SUPPORT_EXTERNAL_SYSTEM_CACHE =
+      CONFIG_MDFD_GL3 =
+   endif
+endif
+
+ifeq ($(CONFIG_MDFD_HDMI_PR2),y)
+   GL3_EXTERNAL_SYSTEM_CACHE ?=1
+   ifeq ($(GL3_EXTERNAL_SYSTEM_CACHE),1)
+      SUPPORT_EXTERNAL_SYSTEM_CACHE = y
+      CONFIG_MDFD_GL3 = y
+   else
+      SUPPORT_EXTERNAL_SYSTEM_CACHE =
+      CONFIG_MDFD_GL3 =
+   endif
+endif
+
+ccflags-$(SUPPORT_EXTERNAL_SYSTEM_CACHE) += -DSUPPORT_EXTERNAL_SYSTEM_CACHE -DCONFIG_MDFD_GL3
+ccflags-y += $(INCLUDE_PATH) $(include_dirs)
+#uncomment for debug prints
+#ccflags-y += -DDEBUG
+
+ifeq ($(CONFIG_MDFD_HDMI_GREENRIDGE),y)
+   INCLUDE_PATH += -I$(OTM_HDMI_INCDIR)/pil/specific/oktl
+   INCLUDE_PATH += -I$(OTM_HDMI_INCDIR)/ipil/specific/oktl-sdv
+else ifeq ($(CONFIG_MDFD_HDMI_REDRIDGE),y)
+      INCLUDE_PATH += -I$(OTM_HDMI_INCDIR)/pil/specific/mfld
+      INCLUDE_PATH += -I$(OTM_HDMI_INCDIR)/ipil/specific/mfld
+else ifeq ($(CONFIG_MDFD_HDMI_PR2),y)
+      INCLUDE_PATH += -I$(OTM_HDMI_INCDIR)/pil/specific/mfld
+      INCLUDE_PATH += -I$(OTM_HDMI_INCDIR)/ipil/specific/mfld
+endif
+
+# Platform independent library
+$(TARGET)-y := pil/common/otm_hdmi.o
+$(TARGET)-y += pil/common/mode_info.o
+$(TARGET)-y += pil/common/hdcp.o
+$(TARGET)-y += pil/common/edid.o
+$(TARGET)-y += pil/common/edid_print.o
+$(TARGET)-y += pil/common/infoframes.o
+
+# IP independent library
+$(TARGET)-y += ipil/common/otm_ipil_main.o
+$(TARGET)-y += ipil/common/ipil_hdcp.o
+
+# OS specific library
+$(TARGET)-y += os/android/android_hdmi.o
+ifneq ($(CONFIG_MDFD_HDMI_REDRIDGE),y)
+$(TARGET)-y += os/android/android_hdmi_sw_scale.o
+endif
+
+ifeq ($(CONFIG_MDFD_HDMI_GREENRIDGE),y)
+   $(TARGET)-y += ipil/specific/oktl-sdv/ips_hdmi.o
+   $(TARGET)-y += ipil/specific/oktl-sdv/ips_hdcp.o
+   $(TARGET)-y += pil/specific/oktl/ps_hdmi.o
+   obj-$(CONFIG_DRM_MRST) += $(TARGET).o
+else ifeq ($(CONFIG_MDFD_HDMI_REDRIDGE),y)
+      $(TARGET)-y += ipil/specific/mfld/ips_hdmi.o
+      $(TARGET)-y += ipil/specific/mfld/ips_hdcp.o
+      $(TARGET)-y += pil/specific/mfld/ps_hdmi.o
+      $(TARGET)-y += pil/specific/mfld/ps_hdmi_tablet.o
+      obj-$(CONFIG_DRM_MDFLD) += $(TARGET).o
+else ifeq ($(CONFIG_MDFD_HDMI_PR2),y)
+      $(TARGET)-y += ipil/specific/mfld/ips_hdmi.o
+      $(TARGET)-y += ipil/specific/mfld/ips_hdcp.o
+      $(TARGET)-y += pil/specific/mfld/ps_hdmi.o
+      $(TARGET)-y += pil/specific/mfld/ps_hdmi_phone.o
+      obj-$(CONFIG_DRM_MDFLD) += $(TARGET).o
+endif
diff --git a/drivers/staging/mrst/drv/otm_hdmi/ipil/common/ipil_hdcp.c b/drivers/staging/mrst/drv/otm_hdmi/ipil/common/ipil_hdcp.c
new file mode 100644 (file)
index 0000000..146759e
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+
+#include <linux/types.h>
+#include "hdcp_rx_defs.h"
+#include "ips_hdcp_api.h"
+
+
+bool ipil_hdcp_is_ready(void)
+{
+       return ips_hdcp_is_ready();
+}
+
+bool ipil_hdcp_get_an(uint8_t *an, uint32_t size)
+{
+       bool ret = false;
+       if (an != NULL && size == HDCP_AN_SIZE) {
+               ips_hdcp_get_an(an);
+               ret = true;
+       }
+       return ret;
+}
+
+bool ipil_hdcp_get_aksv(uint8_t *aksv, uint32_t size)
+{
+       bool ret = false;
+       if (aksv != NULL  && size == HDCP_KSV_SIZE) {
+               ips_hdcp_get_aksv(aksv);
+               ret = true;
+       }
+       return ret;
+}
+
+bool ipil_hdcp_set_repeater(bool present)
+{
+       return ips_hdcp_set_repeater(present);
+}
+
+bool ipil_hdcp_set_bksv(uint8_t *bksv)
+{
+       return ips_hdcp_set_bksv(bksv);
+}
+
+bool ipil_hdcp_start_authentication(void)
+{
+       return ips_hdcp_start_authentication();
+}
+
+bool ipil_hdcp_is_r0_ready(void)
+{
+       return ips_hdcp_is_r0_ready();
+}
+
+bool ipil_hdcp_does_ri_match(uint16_t rx_ri)
+{
+       return ips_hdcp_does_ri_match(rx_ri);
+}
+
+bool ipil_hdcp_enable_encryption(void)
+{
+       return ips_hdcp_enable_encryption();
+}
+
+bool ipil_hdcp_disable(void)
+{
+       return ips_hdcp_disable();
+}
+
+bool ipil_hdcp_device_can_authenticate(void)
+{
+       return ips_hdcp_device_can_authenticate();
+}
+
+bool ipil_hdcp_init(void)
+{
+       return ips_hdcp_init();
+}
+
diff --git a/drivers/staging/mrst/drv/otm_hdmi/ipil/common/ipil_internal.h b/drivers/staging/mrst/drv/otm_hdmi/ipil/common/ipil_internal.h
new file mode 100644 (file)
index 0000000..ad79512
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef __IPIL_INTERNAL_H
+#define __IPIL_INTERNAL_H
+
+#include "ips_hdmi.h"
+
+/* hdmi display related registers */
+#define IPIL_DSPBASE           IPS_DSPBASE
+#define IPIL_DSPBSIZE          IPS_DSPBSIZE
+#define IPIL_PIPEBSRC          IPS_PIPEBSRC
+#define IPIL_DSPBPOS           IPS_DSPBPOS
+#define IPIL_PFIT_CONTROL      IPS_PFIT_CONTROL
+#define IPIL_HTOTAL_B          IPS_HTOTAL_B
+#define IPIL_VTOTAL_B          IPS_VTOTAL_B
+#define IPIL_HBLANK_B          IPS_HBLANK_B
+#define IPIL_VBLANK_B          IPS_VBLANK_B
+#define IPIL_HSYNC_B           IPS_HSYNC_B
+#define IPIL_VSYNC_B           IPS_VSYNC_B
+#define IPIL_DPLL_B                IPS_DPLL_B
+#define IPIL_DPLL_DIV0         IPS_DPLL_DIV0
+#define IPIL_PIPEBCONF         IPS_PIPEBCONF
+#define IPIL_DSPBCNTR          IPS_DSPBCNTR
+#define IPIL_HDMIB_CONTROL  IPS_HDMIB_CONTROL
+#define IPIL_DSPBSTRIDE     IPS_DSPBSTRIDE
+#define IPIL_DSPBLINOFF     IPS_DSPBLINOFF
+#define IPIL_DSPBTILEOFF    IPS_DSPBTILEOFF
+#define IPIL_DSPBSURF       IPS_DSPBSURF
+#define IPIL_DSPBSTAT       IPS_DSPBSTAT
+#define IPIL_PALETTE_B      IPS_PALETTE_B
+#define IPIL_PFIT_PGM_RATIOS     IPS_PFIT_PGM_RATIOS
+#define IPIL_HDMIPHYMISCCTL      IPS_HDMIPHYMISCCTL
+
+#define IPIL_VGACNTRL 0x71400
+#define IPIL_DPLL_PWR_GATE_EN (1<<30)
+#define IPIL_DPLL_VCO_ENABLE (1<<31)
+#define IPIL_VGA_DISP_DISABLE (1<<31)
+
+/* TODO: revisit this. make then IP specific */
+#define IPIL_PFIT_ENABLE               (1 << 31)
+#define IPIL_PFIT_PIPE_SHIFT           29
+#define IPIL_PFIT_PIPE_SELECT_B                (1 << IPIL_PFIT_PIPE_SHIFT)
+#define IPIL_PFIT_SCALING_AUTO         (0 << 26)
+#define IPIL_PFIT_SCALING_PILLARBOX    (1 << 27)
+#define IPIL_PFIT_SCALING_LETTERBOX    (3 << 26)
+
+#define IPIL_DPLL_VCO_ENABLE   (1 << 31)
+#define IPIL_PWR_GATE_EN       (1 << 30)
+#define IPIL_PIPECONF_PLL_LOCK (1<<29)
+#define IPIL_DSP_PLANE_PIPE_POS        24
+#define IPIL_DSP_PLANE_ENABLE  (1<<31)
+#define IPIL_PIPEACONF_ENABLE  (1<<31)
+#define IPIL_PIPEACONF_PIPE_STATE    (1<<30)
+#define IPIL_PIPECONF_PLANE_OFF  (1<<19)
+#define IPIL_PIPECONF_CURSOR_OFF     (1<<18)
+#define IPIL_P1_MASK           (0x1FF << 17)
+#define IPIL_HDMIB_PORT_EN     (1 << 31)
+#define IPIL_HDMIB_PIPE_B_SELECT (1 << 30)
+#define IPIL_HDMIB_NULL_PACKET (1 << 9)
+#define IPIL_HDMIB_AUDIO_ENABLE        (1 << 6)
+#define IPIL_HDMI_PHY_POWER_DOWN 0x7f
+
+#define IPIL_TIMING_FLAG_PHSYNC        (1<<0)
+#define IPIL_TIMING_FLAG_NHSYNC        (1<<1)
+#define IPIL_TIMING_FLAG_PVSYNC        (1<<2)
+#define IPIL_TIMING_FLAG_NVSYNC        (1<<3)
+
+struct ipil_clock_t {
+       int dot;
+       int m;
+       int p1;
+};
+
+struct ipil_range_t {
+       int min, max;
+};
+
+struct ipil_clock_limits_t {
+       struct ipil_range_t dot, m, p1;
+};
+
+void hdmi_write32(uint32_t reg, uint32_t val);
+uint32_t hdmi_read32(uint32_t reg);
+
+#endif /* __IPIL_INTERNAL_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/ipil/common/otm_ipil_main.c b/drivers/staging/mrst/drv/otm_hdmi/ipil/common/otm_ipil_main.c
new file mode 100644 (file)
index 0000000..34b1529
--- /dev/null
@@ -0,0 +1,755 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <asm/io.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include "ipil_internal.h"
+
+#include "otm_hdmi.h"
+#include "otm_hdmi_types.h"
+
+#include "ips_hdmi.h"
+
+static hdmi_device_t *hdmi_dev;
+
+otm_hdmi_ret_t ipil_hdmi_set_hdmi_dev(hdmi_device_t *dev)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       if (!dev)
+               rc = OTM_HDMI_ERR_NULL_ARG;
+       else
+               hdmi_dev = dev;
+       return rc;
+}
+
+uint32_t hdmi_read32(uint32_t reg)
+{
+       if (hdmi_dev)
+               return readl((const void *)(hdmi_dev->io_address + reg));
+
+       return 0;
+}
+
+void hdmi_write32(uint32_t reg, uint32_t val)
+{
+       if (hdmi_dev)
+               writel(val, (void *)(hdmi_dev->io_address + reg));
+}
+
+otm_hdmi_ret_t ipil_hdmi_decide_I2C_HW(hdmi_context_t *ctx)
+{
+       return ips_hdmi_decide_I2C_HW(ctx);
+}
+
+otm_hdmi_ret_t ipil_hdmi_general_5V_enable(hdmi_device_t *dev)
+{
+       return ips_hdmi_general_5V_enable(dev);
+}
+
+otm_hdmi_ret_t ipil_hdmi_general_5V_disable(hdmi_device_t *dev)
+{
+       return ips_hdmi_general_5V_disable(dev);
+}
+
+otm_hdmi_ret_t ipil_hdmi_set_program_clocks(hdmi_context_t *ctx,
+                                           unsigned int dclk)
+{
+       return ips_hdmi_set_program_clocks(ctx, dclk);
+}
+
+otm_hdmi_ret_t ipil_hdmi_audio_init(hdmi_context_t *ctx)
+{
+       return ips_hdmi_audio_init(ctx);
+}
+
+otm_hdmi_ret_t ipil_hdmi_audio_deinit(hdmi_context_t *ctx)
+{
+       return ips_hdmi_audio_deinit(ctx);
+}
+
+otm_hdmi_ret_t ipil_hdmi_general_unit_enable(hdmi_device_t *dev)
+{
+       return ips_hdmi_general_unit_enable(dev);
+}
+
+otm_hdmi_ret_t ipil_hdmi_general_unit_disable(hdmi_device_t *dev)
+{
+       return ips_hdmi_general_unit_disable(dev);
+}
+
+otm_hdmi_ret_t ipil_hdmi_general_hdcp_clock_enable(hdmi_device_t *dev)
+{
+       return ips_hdmi_general_hdcp_clock_enable(dev);
+}
+
+otm_hdmi_ret_t ipil_hdmi_general_hdcp_clock_disable(hdmi_device_t *dev)
+{
+       return ips_hdmi_general_hdcp_clock_disable(dev);
+}
+
+otm_hdmi_ret_t ipil_hdmi_general_audio_clock_enable(hdmi_device_t *dev)
+{
+       return ips_hdmi_general_audio_clock_enable(dev);
+}
+
+otm_hdmi_ret_t ipil_hdmi_general_audio_clock_disable(hdmi_device_t *dev)
+{
+       return ips_hdmi_general_audio_clock_disable(dev);
+}
+
+otm_hdmi_ret_t ipil_hdmi_general_pixel_clock_enable(hdmi_device_t *dev)
+{
+       return ips_hdmi_general_pixel_clock_enable(dev);
+}
+
+otm_hdmi_ret_t ipil_hdmi_general_pixel_clock_disable(hdmi_device_t *dev)
+{
+       return ips_hdmi_general_pixel_clock_disable(dev);
+}
+
+otm_hdmi_ret_t ipil_hdmi_general_tdms_clock_enable(hdmi_device_t *dev)
+{
+       return ips_hdmi_general_tdms_clock_enable(dev);
+}
+
+otm_hdmi_ret_t ipil_hdmi_general_tdms_clock_disable(hdmi_device_t *dev)
+{
+       return ips_hdmi_general_tdms_clock_disable(dev);
+}
+
+otm_hdmi_ret_t ipil_hdmi_i2c_disable(hdmi_device_t *dev)
+{
+       return ips_hdmi_i2c_disable(dev);
+}
+
+bool ipil_hdmi_power_rails_on()
+{
+       return ips_hdmi_power_rails_on();
+}
+
+/*
+ * Description: hdmi interrupt handler (upper half).
+ *             handles the interrupts by reading hdmi status register
+ *             and waking up bottom half if needed.
+ *
+ * @dev:       hdmi_device_t
+ *
+ * Returns:    IRQ_HANDLED on NULL input arguments, and if the
+ *                     interrupt is not HDMI HPD interrupts.
+ *             IRQ_WAKE_THREAD if this is a HDMI HPD interrupt.
+ */
+irqreturn_t ipil_hdmi_irq_handler(hdmi_device_t *dev)
+{
+       /* NULL checks */
+       if (dev == NULL) {
+               pr_debug("\ninvalid argument\n");
+               return IRQ_HANDLED;
+       }
+
+       return ips_hdmi_irq_handler((void *)dev->irq_io_address);
+}
+
+/*
+ * Description: enable infoframes
+ *
+ * @dev:        hdmi_device_t
+ * @type:      type of infoframe packet
+ * @pkt:       infoframe packet data
+ * @freq:      number of times packet needs to be sent
+ *
+ * Returns:     OTM_HDMI_ERR_NULL_ARG on NULL parameters
+ *             OTM_HDMI_ERR_INVAL on invalid packet type
+ *             OTM_HDMI_SUCCESS on success
+ */
+otm_hdmi_ret_t ipil_hdmi_enable_infoframe(hdmi_device_t *dev,
+               unsigned int type, otm_hdmi_packet_t *pkt, unsigned int freq)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+
+       if (!dev || !pkt)
+               return OTM_HDMI_ERR_NULL_ARG;
+
+       switch (type) {
+       case HDMI_PACKET_AVI:
+       case HDMI_PACKET_VS:
+       case HDMI_PACKET_SPD:
+               rc = ips_hdmi_enable_vid_infoframe(dev, type, pkt, freq);
+               break;
+       default:/* TODO: Revisit for Other Infoframes */
+               rc = OTM_HDMI_ERR_INVAL;
+               break;
+       }
+
+       return rc;
+}
+
+/*
+ * Description: disable particular infoframe
+ *
+ * @dev:        hdmi_device_t
+ * @type:      type of infoframe packet
+ *
+ * Returns:     OTM_HDMI_ERR_NULL_ARG on NULL parameters
+ *             OTM_HDMI_ERR_INVAL on invalid packet type
+ *             OTM_HDMI_SUCCESS on success
+*/
+otm_hdmi_ret_t ipil_hdmi_disable_infoframe(hdmi_device_t *dev,
+                                       unsigned int type)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+
+       if (!dev)
+               return OTM_HDMI_ERR_NULL_ARG;
+
+       switch (type) {
+       case HDMI_PACKET_AVI:
+       case HDMI_PACKET_VS:
+       case HDMI_PACKET_SPD:
+               rc = ips_hdmi_disable_vid_infoframe(dev, type);
+               break;
+       default:/* TODO: Revisit for Other Infoframes */
+               rc = OTM_HDMI_ERR_INVAL;
+               break;
+       }
+
+       return rc;
+}
+
+/*
+ * Description: disable all infoframes
+ *
+ * @dev:        hdmi_device_t
+ *
+ * Returns:     OTM_HDMI_ERR_NULL_ARG on NULL parameters
+ *             OTM_HDMI_SUCCESS on success
+*/
+otm_hdmi_ret_t ipil_hdmi_disable_all_infoframes(hdmi_device_t *dev)
+{
+       if (!dev)
+               return OTM_HDMI_ERR_NULL_ARG;
+
+       return ips_hdmi_disable_all_infoframes(dev);
+}
+
+/*
+ * Description: programs hdmi pipe src and size of the input.
+ *
+ * @dev:               hdmi_device_t
+ * @scalingtype:       scaling type (FULL_SCREEN, CENTER, NO_SCALE etc.)
+ * @mode:              mode requested
+ * @adjusted_mode:     adjusted mode
+ * @fb_width, fb_height:allocated frame buffer dimensions
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t ipil_hdmi_crtc_mode_set_program_dspregs(hdmi_device_t *dev,
+                                       int scalingtype,
+                                       ipil_timings_t *mode,
+                                       ipil_timings_t *adjusted_mode,
+                                       int fb_width, int fb_height)
+{
+       int sprite_pos_x = 0, sprite_pos_y = 0;
+       int sprite_width = 0, sprite_height = 0;
+       int src_image_hor = 0, src_image_vert = 0;
+
+       /* NULL checks */
+       if (dev == NULL || mode == NULL || adjusted_mode == NULL) {
+               pr_debug("\ninvalid argument\n");
+               return OTM_HDMI_ERR_INVAL;
+       }
+
+       /*
+        * TODO: update these values based on scaling type,
+        * rotation and HDMI mode.
+        */
+       sprite_width = fb_width;
+       sprite_height = fb_height;
+       src_image_hor = fb_width;
+       src_image_vert = fb_height;
+       sprite_pos_x = 0;
+       sprite_pos_y = 0;
+
+       /*
+        * pipesrc and dspsize control the size that is scaled from,
+        * which should always be the user's requested size.
+        */
+       switch (scalingtype) {
+       case IPIL_TIMING_SCALE_NONE:
+       case IPIL_TIMING_SCALE_CENTER:
+               /* TODO: implement this */
+               break;
+
+       case IPIL_TIMING_SCALE_FULLSCREEN:
+               if ((adjusted_mode->width != sprite_width) ||
+                       (adjusted_mode->height != sprite_height))
+                       hdmi_write32(IPIL_PFIT_CONTROL,
+                               IPIL_PFIT_ENABLE |
+                               IPIL_PFIT_PIPE_SELECT_B |
+                               IPIL_PFIT_SCALING_AUTO);
+
+               break;
+
+       case IPIL_TIMING_SCALE_ASPECT:
+               if ((adjusted_mode->width != fb_width) ||
+                       (adjusted_mode->height != fb_height)) {
+                       if ((adjusted_mode->width * fb_height) ==
+                           (fb_width * adjusted_mode->height))
+                               hdmi_write32(IPIL_PFIT_CONTROL,
+                                       IPIL_PFIT_ENABLE |
+                                       IPIL_PFIT_PIPE_SELECT_B);
+                       else if ((adjusted_mode->width *
+                               fb_height) > (fb_width *
+                               adjusted_mode->height))
+                               hdmi_write32(IPIL_PFIT_CONTROL,
+                                       IPIL_PFIT_ENABLE |
+                                       IPIL_PFIT_PIPE_SELECT_B |
+                                       IPIL_PFIT_SCALING_PILLARBOX);
+                       else
+                               hdmi_write32(IPIL_PFIT_CONTROL,
+                                       IPIL_PFIT_ENABLE |
+                                       IPIL_PFIT_PIPE_SELECT_B |
+                                       IPIL_PFIT_SCALING_LETTERBOX);
+               }
+               break;
+
+       default:
+               if ((adjusted_mode->width != fb_width) ||
+                       (adjusted_mode->height != fb_height))
+                       hdmi_write32(IPIL_PFIT_CONTROL,
+                                       IPIL_PFIT_ENABLE |
+                                       IPIL_PFIT_PIPE_SELECT_B);
+
+               break;
+       }
+
+       hdmi_write32(IPIL_DSPBSIZE, ((sprite_height - 1) << 16) |
+                                (sprite_width - 1));
+
+       hdmi_write32(IPIL_PIPEBSRC, ((src_image_hor - 1) << 16) |
+                               (src_image_vert - 1));
+
+       hdmi_write32(IPIL_DSPBPOS, (sprite_pos_y << 16) | sprite_pos_x);
+
+       return OTM_HDMI_SUCCESS;
+}
+
+/*
+ * Description: this is pre-modeset configuration. This can be
+ *             resetting HDMI unit, disabling/enabling dpll etc
+ *             on the need basis.
+ *
+ * @dev:       hdmi_device_t
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t ipil_hdmi_crtc_mode_set_prepare(hdmi_device_t *dev)
+{
+       /* NULL checks */
+       if (dev == NULL) {
+               pr_debug("\ninvalid argument\n");
+               return OTM_HDMI_ERR_INVAL;
+       }
+
+       /* Nothing needed as of now for medfield */
+
+       return OTM_HDMI_SUCCESS;
+}
+
+/*
+ * Description: programs all the timing registers based on scaling type.
+ *
+ * @dev:               hdmi_device_t
+ * @scalingtype:       scaling type (FULL_SCREEN, CENTER, NO_SCALE etc.)
+ * @mode:              mode requested
+ * @adjusted_mode:     adjusted mode
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t ipil_hdmi_crtc_mode_set_program_timings(hdmi_device_t *dev,
+                                       int scalingtype,
+                                       otm_hdmi_timing_t *mode,
+                                       otm_hdmi_timing_t *adjusted_mode)
+{
+       /* NULL checks */
+       if (dev == NULL || mode == NULL || adjusted_mode == NULL) {
+               pr_debug("\ninvalid argument\n");
+               return OTM_HDMI_ERR_INVAL;
+       }
+
+       /* TODO: get adjusted htotal */
+       /* ips_hdmi_get_htotal(); */
+
+       if (scalingtype == IPIL_TIMING_SCALE_NONE) {
+               /* Moorestown doesn't have register support for centering so we
+                * need to  mess with the h/vblank and h/vsync start and ends
+                * to get centering
+                */
+               int offsetX = 0, offsetY = 0;
+
+               offsetX = (adjusted_mode->width - mode->width) / 2;
+               offsetY = (adjusted_mode->height - mode->height) / 2;
+
+               hdmi_write32(IPIL_HTOTAL_B, (mode->width - 1) |
+                               ((adjusted_mode->htotal - 1) << 16));
+
+               hdmi_write32(IPIL_VTOTAL_B, (mode->height - 1) |
+                               ((adjusted_mode->vtotal - 1) << 16));
+
+               hdmi_write32(IPIL_HBLANK_B,
+                       (adjusted_mode->hblank_start - offsetX - 1) |
+                       ((adjusted_mode->hblank_end - offsetX - 1) << 16));
+
+               hdmi_write32(IPIL_HSYNC_B,
+                       (adjusted_mode->hsync_start - offsetX - 1) |
+                       ((adjusted_mode->hsync_end - offsetX - 1) << 16));
+
+               hdmi_write32(IPIL_VBLANK_B,
+                       (adjusted_mode->vblank_start - offsetY - 1) |
+                       ((adjusted_mode->vblank_end - offsetY - 1) << 16));
+
+               hdmi_write32(IPIL_VSYNC_B,
+                       (adjusted_mode->vsync_start - offsetY - 1) |
+                       ((adjusted_mode->vsync_end - offsetY - 1) << 16));
+       } else {
+               hdmi_write32(IPIL_HTOTAL_B,
+                               (adjusted_mode->width - 1) |
+                               ((adjusted_mode->htotal - 1) << 16));
+
+               hdmi_write32(IPIL_VTOTAL_B,
+                               (adjusted_mode->height - 1) |
+                               ((adjusted_mode->vtotal - 1) << 16));
+
+               hdmi_write32(IPIL_HBLANK_B,
+                               (adjusted_mode->hblank_start - 1) |
+                               ((adjusted_mode->hblank_end - 1) << 16));
+
+               hdmi_write32(IPIL_HSYNC_B,
+                               (adjusted_mode->hsync_start - 1) |
+                               ((adjusted_mode->hsync_end - 1) << 16));
+
+               hdmi_write32(IPIL_VBLANK_B,
+                               (adjusted_mode->vblank_start - 1) |
+                               ((adjusted_mode->vblank_end - 1) << 16));
+
+               hdmi_write32(IPIL_VSYNC_B,
+                               (adjusted_mode->vsync_start - 1) |
+                               ((adjusted_mode->vsync_end - 1) << 16));
+       }
+
+       return OTM_HDMI_SUCCESS;
+}
+
+/*
+ * Description: programs dpll clocks, enables dpll and waits
+ *             till it locks with DSI PLL
+ *
+ * @dev:       hdmi_device_t
+ * @dclk:      refresh rate dot clock in kHz of current mode
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t ipil_hdmi_crtc_mode_set_program_dpll(hdmi_device_t *dev,
+                                                       unsigned long dclk)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       u32 dpll_adj, fp;
+       u32 dpll;
+       int timeout = 0;
+
+       /* NULL checks */
+       if (dev == NULL) {
+               pr_debug("\ninvalid argument\n");
+               return OTM_HDMI_ERR_INVAL;
+       }
+
+       /* get the adjusted clock value */
+       rc = ips_hdmi_get_adjusted_clk(dclk, &dpll_adj, &fp, &dev->clock_khz);
+       if (rc != OTM_HDMI_SUCCESS) {
+               pr_debug("\nfailed to calculate adjusted clock\n");
+               return rc;
+       }
+
+       dpll = hdmi_read32(IPIL_DPLL_B);
+       if (dpll & IPIL_DPLL_VCO_ENABLE) {
+               dpll &= ~IPIL_DPLL_VCO_ENABLE;
+               hdmi_write32(IPIL_DPLL_B, dpll);
+               hdmi_read32(IPIL_DPLL_B);
+
+               /* reset M1, N1 & P1 */
+               hdmi_write32(IPIL_DPLL_DIV0, 0);
+               dpll &= ~IPIL_P1_MASK;
+               hdmi_write32(IPIL_DPLL_B, dpll);
+       }
+
+       /*
+        * When ungating power of DPLL, needs to wait 0.5us
+        * before enable the VCO
+        */
+       if (dpll & IPIL_PWR_GATE_EN) {
+               dpll &= ~IPIL_PWR_GATE_EN;
+               hdmi_write32(IPIL_DPLL_B, dpll);
+               udelay(1);
+       }
+
+       dpll = dpll_adj;
+       hdmi_write32(IPIL_DPLL_DIV0, fp);
+       hdmi_write32(IPIL_DPLL_B, dpll);
+       udelay(1);
+
+       dpll |= IPIL_DPLL_VCO_ENABLE;
+       hdmi_write32(IPIL_DPLL_B, dpll);
+       hdmi_read32(IPIL_DPLL_B);
+
+       /* wait for DSI PLL to lock */
+       while ((timeout < 20000) && !(hdmi_read32(IPIL_PIPEBCONF) &
+                                       IPIL_PIPECONF_PLL_LOCK)) {
+               udelay(150);
+               timeout++;
+       }
+
+       return OTM_HDMI_SUCCESS;
+}
+
+/*
+ * Description: configures the display plane register and enables
+ *             pipeconf.
+ *
+ * @dev: hdmi_device_t
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t ipil_hdmi_crtc_mode_set_program_pipeconf(hdmi_device_t *dev)
+{
+       u32 dspcntr;
+       u32 pipeconf;
+
+       /* NULL checks */
+       if (dev == NULL) {
+               pr_debug("\ninvalid argument\n");
+               return OTM_HDMI_ERR_INVAL;
+       }
+
+       /* Set up the display plane register */
+       dspcntr = hdmi_read32(IPIL_DSPBCNTR);
+       dspcntr |= 1 << IPIL_DSP_PLANE_PIPE_POS;
+       dspcntr |= IPIL_DSP_PLANE_ENABLE;
+
+       /* setup pipeconf */
+       pipeconf = IPIL_PIPEACONF_ENABLE;
+
+
+       hdmi_write32(IPIL_PIPEBCONF, pipeconf);
+       hdmi_read32(IPIL_PIPEBCONF);
+
+       hdmi_write32(IPIL_DSPBCNTR, dspcntr);
+
+       return OTM_HDMI_SUCCESS;
+}
+
+/*
+ * Description: encoder mode set function for hdmi. enables phy.
+ *             set correct polarity for the current mode, sets
+ *             correct panel fitting.
+ *
+ *
+ * @dev:               hdmi_device_t
+ * @mode:              mode requested
+ * @adjusted_mode:     adjusted mode
+ * @is_monitor_hdmi:   is monitor type is hdmi or not
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t ipil_hdmi_enc_mode_set(hdmi_device_t *dev,
+                                       otm_hdmi_timing_t *mode,
+                                       otm_hdmi_timing_t *adjusted_mode,
+                                       bool is_monitor_hdmi)
+{
+       u32 hdmib, hdmi_phy_misc;
+       bool phsync;
+       bool pvsync;
+
+       /* NULL checks */
+       if (dev == NULL || mode == NULL || adjusted_mode == NULL) {
+               pr_debug("\ninvalid argument\n");
+               return OTM_HDMI_ERR_INVAL;
+       }
+
+       if (is_monitor_hdmi) {
+               hdmib = hdmi_read32(IPIL_HDMIB_CONTROL) | IPIL_HDMIB_PORT_EN
+                                               | IPIL_HDMIB_PIPE_B_SELECT
+                                               | IPIL_HDMIB_NULL_PACKET
+                                               | IPIL_HDMIB_AUDIO_ENABLE;
+       } else {
+               hdmib = hdmi_read32(IPIL_HDMIB_CONTROL) | IPIL_HDMIB_PORT_EN
+                                               | IPIL_HDMIB_PIPE_B_SELECT;
+               hdmib &= ~IPIL_HDMIB_NULL_PACKET;
+               hdmib &= ~IPIL_HDMIB_AUDIO_ENABLE;
+       }
+
+       /* set output polarity */
+       phsync = adjusted_mode->mode_info_flags & IPIL_TIMING_FLAG_PHSYNC;
+       pvsync = adjusted_mode->mode_info_flags & IPIL_TIMING_FLAG_PVSYNC;
+       pr_debug("enc_mode_set %dx%d (%c,%c)\n", adjusted_mode->width,
+                                               adjusted_mode->height,
+                                               phsync ? '+' : '-',
+                                               pvsync ? '+' : '-');
+       /* TODO: define macros for hard coded values */
+       hdmib &= ~0x18; /* clean bit 3 and 4 */
+       hdmib |= phsync ? 0x8  : 0x0; /* bit 3 */
+       hdmib |= pvsync ? 0x10 : 0x0; /* bit 4 */
+
+       hdmi_phy_misc = hdmi_read32(IPIL_HDMIPHYMISCCTL) &
+                                       ~IPIL_HDMI_PHY_POWER_DOWN;
+
+       hdmi_write32(IPIL_HDMIPHYMISCCTL, hdmi_phy_misc);
+       hdmi_write32(IPIL_HDMIB_CONTROL, hdmib);
+       hdmi_read32(IPIL_HDMIB_CONTROL);
+
+       return OTM_HDMI_SUCCESS;
+}
+
+/*
+ * Description: save HDMI display registers
+ *
+ * @dev:               hdmi_device_t
+ *
+ * Returns: none
+ */
+void ipil_hdmi_save_display_registers(hdmi_device_t *dev)
+{
+       if (NULL != dev)
+               ips_hdmi_save_display_registers(dev);
+}
+
+/*
+ * Description: save HDMI data island packets
+ *
+ * @dev:               hdmi_device_t
+ *
+ * Returns: none
+ */
+void ipil_hdmi_save_data_island(hdmi_device_t *dev)
+{
+       if (NULL != dev)
+               ips_hdmi_save_data_island(dev);
+}
+
+/*
+ * Description: destroys any saved HDMI data
+ *
+ * @dev:       hdmi_device_t
+ *
+ * Returns: none
+ */
+void ipil_hdmi_destroy_saved_data(hdmi_device_t *dev)
+{
+       if (NULL != dev)
+               ips_hdmi_destroy_saved_data(dev);
+}
+
+/*
+ * Description: disable HDMI display
+ *
+ * @dev:               hdmi_device_t
+ *
+ * Returns: none
+ */
+void ipil_disable_hdmi(hdmi_device_t *dev)
+{
+       if (NULL != dev)
+               ips_disable_hdmi(dev);
+}
+
+/*
+ * Description: restore HDMI display registers and enable display
+ *
+ * @dev:               hdmi_device_t
+ *
+ * Returns: none
+ */
+void ipil_hdmi_restore_and_enable_display(hdmi_device_t *dev)
+{
+       if (NULL != dev)
+               ips_hdmi_restore_and_enable_display(dev);
+}
+
+/*
+ * Description: restore HDMI data island packets
+ *
+ * @dev:               hdmi_device_t
+ *
+ * Returns: none
+ */
+void ipil_hdmi_restore_data_island(hdmi_device_t *dev)
+{
+       if (NULL != dev)
+               ips_hdmi_restore_data_island(dev);
+}
diff --git a/drivers/staging/mrst/drv/otm_hdmi/ipil/include/hdcp_rx_defs.h b/drivers/staging/mrst/drv/otm_hdmi/ipil/include/hdcp_rx_defs.h
new file mode 100644 (file)
index 0000000..2326ba0
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef HDCP_RX_DEFS_H
+#define HDCP_RX_DEFS_H
+
+#include "hdmi_internal.h"
+
+#define HDCP_PRIMARY_I2C_ADDR  0x3A
+
+#define HDCP_KSV_SIZE          0x05
+#define HDCP_KSV_HAMMING_WT    (20)
+#define HDCP_AN_SIZE           0x08
+#define HDCP_RI_SIZE           0x02
+#define HDCP_PJ_SIZE           0x01
+#define HDCP_V_H_SIZE          (20)
+
+
+#define HDCP_RX_BKSV_ADDR      0x00
+#define HDCP_RX_RI_ADDR                0x08
+#define HDCP_RX_PJ_ADDR                0x0A
+#define HDCP_RX_AKSV_ADDR      0x10
+
+#define HDCP_RX_AINFO_ADDR     0x15
+#define HDCP_RX_AINFO_SIZE     0x01
+
+#define HDCP_RX_AN_ADDR                0x18
+
+#define HDCP_RX_V_H_ADDR       0x20
+
+#define HDCP_RX_V_H0_ADDR      0x20
+#define HDCP_RX_V_H0_SIZE      0x04
+
+#define HDCP_RX_V_H1_ADDR      0x24
+#define HDCP_RX_V_H1_SIZE      0x04
+
+#define HDCP_RX_V_H2_ADDR      0x28
+#define HDCP_RX_V_H2_SIZE      0x04
+
+#define HDCP_RX_V_H3_ADDR      0x2C
+#define HDCP_RX_V_H3_SIZE      0x04
+
+#define HDCP_RX_V_H4_ADDR      0x30
+#define HDCP_RX_V_H4_SIZE      0x04
+
+#define HDCP_RX_BCAPS_ADDR     0x40
+#define HDCP_RX_BCAPS_SIZE     0x01
+
+#define HDCP_RX_BSTATUS_ADDR   0x41
+#define HDCP_RX_BSTATUS_SIZE   0x02
+
+#define HDCP_RX_KSV_FIFO_ADDR  0x43
+
+struct hdcp_rx_bcaps_t {
+       union {
+               uint8_t value;
+               struct {
+                       uint8_t fast_reauthentication:1 ;
+                       uint8_t b1_1_features:1 ;
+                       uint8_t reserved:2 ;
+                       uint8_t fast_transfer:1 ;
+                       uint8_t ksv_fifo_ready:1 ;
+                       uint8_t is_repeater:1 ;
+                       uint8_t hdmi_reserved:1 ;
+               };
+       };
+};
+
+struct hdcp_rx_bstatus_t {
+       union {
+               uint16_t value;
+               struct {
+                       uint16_t device_count:7 ;
+                       uint16_t max_devs_exceeded:1 ;
+                       uint16_t depth:3 ;
+                       uint16_t max_cascade_exceeded:1 ;
+                       uint16_t hdmi_mode:1 ;
+                       uint16_t reserved2:1 ;
+                       uint16_t rsvd:2 ;
+               };
+       };
+};
+
+
+#endif /* HDCP_RX_DEFS_H */
+
diff --git a/drivers/staging/mrst/drv/otm_hdmi/ipil/include/hdmi_hal.h b/drivers/staging/mrst/drv/otm_hdmi/ipil/include/hdmi_hal.h
new file mode 100644 (file)
index 0000000..a753907
--- /dev/null
@@ -0,0 +1,1207 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+/*
+ * GENERAL ASSUMPTIONS / REQUIREMENTS
+ *
+ * 1. HAL entries mentioned in this document are intended to be simple wrappers
+ *    on top of register reads and writes. They should not keep any state
+ *    and should not implement any policies. It is completely up to higher
+ *    levels when and how to use these entries. The only safety checks HAL
+ *    entries should do is for NULL pointers and (in very few cases) for
+ *    correctness of values supplied for register writes (range and alignment
+ *    checks).
+ * 2. HAL should be implemented in such a way that they can be used in both
+ *    both user and kernel space code.
+ * 3. HAL should hide actual register layout where appropriate (infoframes, csc
+ *    coefficients, etc). This objective is not met at the moment since in some
+ *    cases (DMA configuration) we assume that end user knows the register
+ *    layout (at least for now).
+ *
+ * ABBREVIATIONS
+ *
+ * GCP  - General Control Packet
+ * AVI  - Auxiliaty Video Information
+ * ACP  - Audio Content Protection
+ * ISRC - International Standard Recording Code
+ * SPD  - Source Product Description
+ */
+
+#ifndef __HDMI_HAL_H__
+#define __HDMI_HAL_H__
+
+
+#include <linux/types.h>
+
+#include "otm_hdmi_types.h"
+#include "otm_hdmi_defs.h"
+
+/*
+ * This enumeration represents HDMI unit revision
+ */
+typedef enum {
+       HDMI_PCI_REV_CE3100 = 0,
+       HDMI_PCI_REV_CE4100_A0 = 1,
+       HDMI_PCI_REV_CE4100_B012 = 2,
+       HDMI_PCI_REV_CE4200_A0 = 3,
+       HDMI_PCI_REV_CE4200_B0 = 4,
+} hdmi_unit_revision_id_t;
+
+/*
+ * HDMI register state
+ */
+typedef struct {
+       bool valid;
+       uint32_t saveDPLL;
+       uint32_t saveFPA0;
+       uint32_t savePIPEBCONF;
+       uint32_t saveHTOTAL_B;
+       uint32_t saveHBLANK_B;
+       uint32_t saveHSYNC_B;
+       uint32_t saveVTOTAL_B;
+       uint32_t saveVBLANK_B;
+       uint32_t saveVSYNC_B;
+       uint32_t savePIPEBSRC;
+       uint32_t saveDSPBSTRIDE;
+       uint32_t saveDSPBLINOFF;
+       uint32_t saveDSPBTILEOFF;
+       uint32_t saveDSPBSIZE;
+       uint32_t saveDSPBPOS;
+       uint32_t saveDSPBSURF;
+       uint32_t saveDSPBCNTR;
+       uint32_t saveDSPBSTATUS;
+       uint32_t save_palette_b[256];
+       uint32_t savePFIT_CONTROL;
+       uint32_t savePFIT_PGM_RATIOS;
+       uint32_t saveHDMIPHYMISCCTL;
+       uint32_t saveHDMIB_CONTROL;
+} hdmi_register_state_t;
+
+/*
+ * HDMI infoframe information
+ */
+struct hdmi_infoframe_info_t {
+       bool valid;
+       uint32_t freq;
+       otm_hdmi_packet_t pkt;
+};
+
+/*
+ * This structure is used by HAL user to configure and use HAL
+ */
+typedef struct {
+       /* Base address of mapped registers */
+       unsigned int io_address;
+
+       /* Base address of mapped interrupt registers */
+       unsigned int irq_io_address;
+
+       /* Pointer to register read routine */
+       unsigned int (*io_read) (void *uhandle, /* User provided data */
+                               unsigned int base, /* Base address */
+                               unsigned int offset);   /* Register offset */
+
+       /* Pointer to register write routine */
+       void (*io_write) (void *uhandle, /* User provided data */
+                       unsigned int base, /* Base address */
+                       unsigned int offset, /* Register offset */
+                       unsigned int value); /* Value */
+
+       /* Pointer to delay routine */
+        /* Number of usec to sleep */
+       void (*usleep) (unsigned long usec);
+
+       /* Pointer to the data that will be
+        * passed to both io_read and io_write */
+       void *uhandle;
+
+       /* Pointer to the routine invoked at the beginning of every
+        * HAL call */
+       void (*log_entry) (void *uhandle, /* User provided data */
+                          char *foo);  /* Name of the routine */
+
+       /* Pointer to the routine invoked at the end of every
+        * HAL call */
+       void (*log_exit) (void *uhandle, /* User provided data */
+                         char *foo, /* Name of the routine */
+                         int rc); /* Return code */
+
+       /* HDMI unit identifier */
+       hdmi_unit_revision_id_t id;
+
+       /* Pointer to opaque polling timer */
+       void *poll_timer;
+
+       /* Pointer to the polling timer initialization routine */
+       void (*poll_start) (void *poll_timer);
+
+       /* Pointer to the timeout verification routine */
+        bool(*poll_timeout) (void *poll_timer);
+
+       /* Interrupt status to interrupt handling function */
+       unsigned int isr_status;
+
+       /*
+        * TODO: tmds clk value for the best pll found and is needed for audio.
+        * This field has to be moved into OTM audio interfaces
+        * when implemented.
+        */
+       uint32_t clock_khz;
+
+       /* HDMI register value */
+       hdmi_register_state_t reg_state;
+       /* AVI Infoframe - used for suspend resume */
+       struct hdmi_infoframe_info_t avi;
+} hdmi_device_t;
+
+/*
+ * Description: Infoframe handling facility supports two sending rates: one time
+ *              send and every frame send
+ */
+typedef enum {
+       HDMI_INFOFRAME_SEND_ONCE,
+       HDMI_INFOFRAME_SEND_EVERY
+} hdmi_infoframe_frequency_t;
+
+/*
+ * Description: CE 3100 provides SW with 4 slots for infoframes which can be
+ *              sent as often as every frame. This routine loads given
+ *              infoframe into given slot.
+ *
+ * @param [in] slot_number : number of slot; valid range is [1..4]
+ * @param [in] frame       : pointer to the structure representing infoframe
+ */
+otm_hdmi_ret_t hdmi_infoframe_set(hdmi_device_t *dev,
+                               unsigned int slot_number,
+                               otm_hdmi_packet_t *frame);
+
+/*
+ * Description: Setting up sending frequency attribute for given slot
+ *
+ * @param [in] slot_number : slot number; valid range is [1..4]
+ * @param [in] frequency   : sending frequency
+ */
+otm_hdmi_ret_t hdmi_infoframe_set_frequency(hdmi_device_t *dev,
+                               unsigned int slot_number,
+                               hdmi_infoframe_frequency_t frequency);
+
+/*
+ * Description: Enables/disables sending of infoframe from the given slot
+ *
+ * @param [in] slot_number : slot number; valid range is [1..4]
+ */
+otm_hdmi_ret_t hdmi_infoframe_enable(hdmi_device_t *dev,
+                                       unsigned int slot_number);
+otm_hdmi_ret_t hdmi_infoframe_disable(hdmi_device_t *dev,
+                                       unsigned int slot_number);
+
+/*
+ * AUDIO UNIT
+ */
+
+/*
+ * Description: Turns transmission of audio data and CTS/N packets on/off
+ */
+otm_hdmi_ret_t hdmi_audio_enable(hdmi_device_t *dev);
+otm_hdmi_ret_t hdmi_audio_disable(hdmi_device_t *dev);
+
+/*
+ * Description: List of audio formats supported
+ */
+typedef enum {
+       HDMI_AUDIO_FORMAT_LPCM,
+       HDMI_AUDIO_FORMAT_HBR,
+       HDMI_AUDIO_FORMAT_OBA,
+       HDMI_AUDIO_FORMAT_DTS
+} hdmi_audio_format_t;
+
+/*
+ * Description: Setting up given format
+ *
+ * @param [in] format : audio format
+ */
+otm_hdmi_ret_t hdmi_audio_set_format(hdmi_device_t *dev,
+                               hdmi_audio_format_t format);
+
+/*
+ * Description: Number of channels supported
+ */
+typedef enum {
+       HDMI_AUDIO_NUM_CHANNELS_2,
+       HDMI_AUDIO_NUM_CHANNELS_4,
+       HDMI_AUDIO_NUM_CHANNELS_6,
+       HDMI_AUDIO_NUM_CHANNELS_8
+} hdmi_audio_num_channels_t;
+
+/*
+ * Description: Setting up number of channels
+ *
+ * @param [in] nchannels : number of channels
+ */
+otm_hdmi_ret_t hdmi_audio_set_num_channels(hdmi_device_t *dev,
+                                       hdmi_audio_num_channels_t nchannels);
+
+/*
+ * Description: Specifying if sampling frequensy is larger than 192KHz
+ *              Looks like this call is not really needed at the moment.
+ *
+ * @param [in] high_freq : GDL_TRUE  - sampling frequency is larger than
+ *                                     192 KHz
+ *                         GDL_FALSE - sampling frequency is smaller that
+ *                                     192 KHz
+ */
+otm_hdmi_ret_t hdmi_audio_set_high_frequency(hdmi_device_t *dev,
+                                               bool high_freq);
+
+/*
+ * Description: Setting up clock recovery value N
+ *
+ * @param [in] n - N value
+ */
+otm_hdmi_ret_t hdmi_audio_set_clock_recovery_n(hdmi_device_t *dev,
+                                               unsigned int n);
+
+/*
+ * Description: HW computes CTS value based on current N value. CE3100 can
+ *              bypass automatic CTS calculation.
+ *
+ * @param [in] bypass : GDL_FALSE - CTS calculation is done by HW
+ *                      GDL_TRUE  - CTS calculation is done by SW
+ */
+otm_hdmi_ret_t hdmi_audio_set_clock_recovery_cts_bypass(hdmi_device_t *dev,
+                                                       bool bypass);
+
+/*
+ * Description: Setting up clock recovery CTS value when CTS bypass is enabled
+ *
+ * @param [in] cts : CTS value
+ */
+otm_hdmi_ret_t hdmi_audio_set_clock_recovery_cts(hdmi_device_t *dev,
+                                               unsigned int cts);
+
+/*
+ * Description: Setting up audio clock divider register
+ *              End user should compute it as (128 * FS) / 1000
+ *
+ * @param [in] clock_divider : clock divider
+ */
+otm_hdmi_ret_t hdmi_audio_set_clock_divider(hdmi_device_t *dev,
+                                      unsigned int clock_divider);
+
+/*
+ * Description: Setting up FIFO threshold level (in 32 bit words)
+ *              Should be set to FIFO_SIZE - DMA_BURST_SIZE
+ *
+ * @param [in] threshold : FIFO threshold level
+ */
+otm_hdmi_ret_t hdmi_audio_set_fifo_threshold(hdmi_device_t *dev,
+                                       unsigned int threshold);
+
+/*
+ * Description: Audio FIFO size is 192 32 bit words. This routine reads current
+ *              number of words in the FIFO.
+ *
+ * @param [out] level : valid buffer to store number of 32bit words in the FIFO
+ */
+otm_hdmi_ret_t hdmi_audio_get_fifo_level(hdmi_device_t *dev,
+                                       unsigned int *level);
+
+/*
+ * Description: Layout of subpackets in the audio packet
+ */
+typedef enum {
+       HDMI_AUDIO_LAYOUT_0,
+       HDMI_AUDIO_LAYOUT_1
+} hdmi_audio_packet_layout_t;
+
+/*
+ * Description: Setting up subpackets layout bit. Refer to HDMI specs
+ *              version 1.3 section 5.3.4 for details.
+ *
+ * @param [in] layout : audio subpackets layout
+ */
+otm_hdmi_ret_t hdmi_audio_set_packets_layout(hdmi_device_t *dev,
+                                       hdmi_audio_packet_layout_t layout);
+
+/*
+ * Description: Setting up VR and VL bits in all audio subpackets
+ *              Refer to HDMI specs version 1.3 section 5.3.4 for details
+ *
+ * @param [in] valid : GDL_TRUE - bit is on, GDL_FALSE - bit is off
+ */
+otm_hdmi_ret_t hdmi_audio_set_packets_valid_bits(hdmi_device_t *dev,
+                                           bool valid);
+
+/*
+ * Descripton: Setting up B bit for the first or for all subpackets
+ *
+ * @param [in] all : GDL_TRUE  - sets B bit for all valid subpackets
+ *                   GDL_FALSE - sets B bit for the first subpacket only
+ */
+otm_hdmi_ret_t hdmi_audio_set_packets_b_bits(hdmi_device_t *dev,
+                                               bool all);
+
+/*
+ * Description: Setting up flat bits in all audio packets header
+ *              Refer to HDMI specs version 1.3 section 5.3.4 for details
+ *
+ * @param [in] flat : GDL_TRUE - bit is on, GDL_FALSE - bit is off
+ */
+otm_hdmi_ret_t hdmi_audio_set_packets_flat_bits(hdmi_device_t *dev,
+                                               bool flat);
+
+/*
+ * Description: Setting up UR and UL bits in outgoing packets
+ *              When packet layout is set to 0 then UR and UL in all subpackets
+ *              are affected by a pair of bits. Hence 192 packets are affected
+ *              in total. When packet layout is set to 1 then UR and UL in
+ *              individual subpackets are affected. Hence at least 48 packets
+ *              are affected.
+ *
+ * @param [in] data : valid buffer with 12 32-bit words each representing
+ *                    16 packets
+ */
+otm_hdmi_ret_t hdmi_audio_set_packets_user_bits(hdmi_device_t *dev,
+                                               unsigned int *data);
+
+/*
+ * Description: Triggers insertion of user bits into outgoing audio packets
+ */
+otm_hdmi_ret_t hdmi_audio_send_packets_user_bits(hdmi_device_t *dev);
+
+/*
+ * Description: Setting up CR and CL bits in outgoing packets.
+ *              Rules of how many packets are affected are the same as in
+ *              hdmi_audio_set_packets_user_bits call.
+ *              152 subsequent subpackets will have CR and CL set to 0 (??)
+ *
+ * @param [in] data : valid buffer with 2 32-bit words lower 40 bits of which
+ *                    are considered
+ */
+otm_hdmi_ret_t hdmi_audio_set_packets_channel_bits(hdmi_device_t *dev,
+                                               unsigned int *data);
+
+/*
+ * Description: Reading the CR and CL bits in channel status registers.
+ *              152 subsequent subpackets will have CR and CL set to 0 (??)
+ *
+ * @param [out] data : valid buffer with 2 32-bit words lower 40 bits of which
+ *                     are considered
+ */
+otm_hdmi_ret_t hdmi_audio_get_packets_channel_bits(hdmi_device_t *dev,
+                                               unsigned int *data);
+
+/*
+ * Description: Triggers insertion of channle bits into outgoing audio packets
+ */
+otm_hdmi_ret_t hdmi_audio_send_packets_channel_bits(hdmi_device_t *dev);
+
+/*
+ * DMA UNIT
+ *
+ * DMA can be configured to program itself by fetching series of
+ * descriptors. Each descriptor represents data transfer to be done. So
+ * transfering of audio data from audio buffers to the HDMI FIFO involves the
+ * following:
+ * - Audio buffer is devided into number of transfers
+ * - Each transfer is represented by the node in the linked list of descriptors
+ * - DMA NEXT_DESCR reg is set to the address of first descriptor in the list
+ * - Linked-list mode, burst size and other stuff is set in DMA FLAGS register
+ *
+ * SRC_INT and DST_INT interrupts are available to help HAL user monitoring
+ * what transfer from the list is currently in progress. Enabling them requires
+ * hitting SRC_INT/DST_INT bits in FLAGS_MODE register of DMA unit and
+ * bits 5/6 in HDMI interrupt control register.
+ *
+ * HAL provides three levels of DMA access.
+ * 1. End user controls address of first descriptor
+ * 2. End user controls flags register and address of first descriptor
+ * 3. End user has complete control
+ *
+ * Levels 1 and 2 are enough for DMA usage. Level 3 is included in case there
+ * are some cases where levels 1 and 2 are not covering the needs.
+ */
+
+/*
+ * Description: DMA can be programmed to fetch series of descriptors, each of
+ *              which specifies data transfer parameters. The following
+ *              structure represents such a descriptor.
+ */
+typedef struct {
+       /* address of the the next descriptor */
+       unsigned int next_address;
+       /* number of bytes in the current transfer */
+       unsigned int transfer_size;
+       /* address of the user input buffer */
+       unsigned int src_start_address;
+       /* HDMI FIFO address, should be 0x10101010 */
+       unsigned int dst_start_address;
+       unsigned int flags;
+       /* Misc data associated with descriptor */
+       unsigned int misc_data;
+} hdmi_dma_descriptor_t;
+
+/*
+ * Description: Programs DMA with default configuration and start fetching
+ *              sequence. This call is supposed to hide all configuration
+ *              details from end user.
+ *
+ * @param [in] dscr_ph_addr : physical address of first descriptor to fetch
+ */
+otm_hdmi_ret_t hdmi_dma_default_start(hdmi_device_t *dev,
+                               unsigned int dscr_ph_addr);
+
+/*
+ * Description: Stop transfer sequence by hitting BIT0 of OTHER_MODE register
+ *              in DMA unit.
+ */
+otm_hdmi_ret_t hdmi_dma_stop(hdmi_device_t *dev);
+
+/*
+ * Description: Gives end user a default configuration (i.e. the same
+ *              configuration as hdmi_dma_defalt_start sets) so he can apply
+ *              it to every entry of linked list of descriptors.
+ */
+otm_hdmi_ret_t hdmi_dma_get_default_flags(hdmi_device_t *dev,
+                                               unsigned int *flags);
+
+/*
+ * Description: Setting up given configuration of DMA unit and starting the
+ *              fetching sequence. The intention of this call is to give
+ *              end user more control over the DMA unit than in
+ *              hdmi_dma_default_start so user can tweak things a little bit
+ *
+ * @param [in] descr_phys_addr : physical address of first descriptor to fetch
+ * @param [in] flags           : setting for the DMA flags register
+ */
+otm_hdmi_ret_t hdmi_dma_custom_start(hdmi_device_t *dev,
+                               unsigned int descr_phys_addr,
+                               unsigned int flags);
+
+/*
+ * Description: Structure below represtent DMA configuration
+ */
+typedef struct {
+       unsigned int curr_descr;
+       unsigned int next_descr;
+       unsigned int srcdma_start;
+       unsigned int dstdma_start;
+       unsigned int srcdma_size;
+       unsigned int flags_mode;
+       unsigned int other_mode;
+       unsigned int srcdma_bot;
+       unsigned int srcdma_top;
+       unsigned int dstdma_bot;
+       unsigned int dstdma_top;
+       unsigned int dstdma_size;
+       unsigned int srcdma_stop;
+       unsigned int dstdma_stop;
+} hdmi_dma_config_t;
+
+/*
+ * Description: Providing end user with full control over the DMA
+ *
+ * @param [in] dma_config : pointer to dma configuration structure
+ */
+otm_hdmi_ret_t hdmi_dma_config(hdmi_device_t *dev,
+                               hdmi_dma_config_t *dma_config);
+
+/*
+ * VIDEO
+ */
+
+/*
+ * Description: HDMI unit can operate in both HDMI and DVI modes
+ */
+typedef enum {MODE_HDMI, MODE_DVI} hdmi_operation_mode_t;
+
+/*
+ * Description: Selecting mode of operation
+ *
+ * @param [in] mode: mode of operation
+ */
+otm_hdmi_ret_t hdmi_video_set_operation_mode(hdmi_device_t *dev,
+                                       hdmi_operation_mode_t mode);
+
+/*
+ * Description: Setting up pixel depth
+ *
+ * @param [in] pixel_depth : pixel depth
+ */
+otm_hdmi_ret_t hdmi_video_set_pixel_depth(hdmi_device_t *dev,
+                               otm_hdmi_output_pixel_depth_t pixel_depth);
+
+/*
+ * Description: HDMI unit supports dithering from 12 to 10 and 8 bits
+ */
+typedef enum {
+       HDMI_DITHER_OUTPUT_8BITS,
+       HDMI_DITHER_OUTPUT_10BITS
+} hdmi_dither_output_t;
+
+/*
+ * Description: Selecting dither output
+ *
+ * @param [in] output : rounding from 12 bits to 10 or 8 bits
+ */
+otm_hdmi_ret_t hdmi_video_set_dither_output(hdmi_device_t *dev,
+                                       hdmi_dither_output_t output);
+
+/*
+ * Description: HDMI unit can dither, round or don't do anything at all
+ */
+typedef enum {
+       HDMI_DITHER_DITHER,
+       HDMI_DITHER_ROUND,
+       HDMI_DITHER_BYPASS
+} hdmi_dither_t;
+
+/*
+ * Description: Choosing dithering
+ *
+ * @param [in] dither - selection of particular dithering
+ */
+otm_hdmi_ret_t hdmi_video_set_dither(hdmi_device_t *dev, hdmi_dither_t dither);
+
+/*
+ * Description: Enables/disables CSC
+ *
+ * @param [in] state : GDL_TRUE - CSC is ON, GDL_FALSE - CSC is off
+ */
+otm_hdmi_ret_t hdmi_video_set_csc(hdmi_device_t *dev, bool state);
+
+/*
+ * Descripton: Set additional 444 to 422 conversion. Assumption is that either
+ *             pipe outputs 444 or we already convert to 444 prior to this 422
+ *             conversion. Note that dithering is bypassed when 422 conversion
+ *             is on.
+ *
+ * @param [in] state : GDL_TRUE  - perform additional 422 conversion
+ *                     GDL_FALSE - do not perform additional 422 conversion
+ *
+ * @param [in] sd    : GDL_TRUE  - Current mode is SD
+ *                     GDL_FALSE - Current mode is HD
+ */
+otm_hdmi_ret_t hdmi_video_set_csc_422(hdmi_device_t *dev,
+                               bool state,
+                               bool sd);
+
+/*
+ * Description: offset setup
+ *
+ * @param [in] in  :
+ * @param [in] out :
+ */
+otm_hdmi_ret_t hdmi_video_set_csc_offset_YG(hdmi_device_t *dev,
+                                       int in, int out);
+otm_hdmi_ret_t hdmi_video_set_csc_offset_CbB(hdmi_device_t *dev,
+                                       int in, int out);
+otm_hdmi_ret_t hdmi_video_set_csc_offset_CrR(hdmi_device_t *dev,
+                                       int in, int out);
+
+/*
+ * Description: this structure reflects clamp configuration register
+ */
+typedef struct {
+       bool full_overrun;
+       bool shift_output;
+       bool output_clamp_960;
+       bool output_clamp_enable;
+       bool input_clamp_960;
+       bool input_clamp_enable;
+} hdmi_csc_clamp_t;
+
+/*
+ * Description: Clamp setup
+ *
+ * @param [in] clamp : user supplied buffer with clamp configuration
+ */
+otm_hdmi_ret_t hdmi_video_set_csc_clamp(hdmi_device_t *dev,
+                               hdmi_csc_clamp_t *clamp);
+
+/*
+ * Color space conversion coefficients are exposed keeping the following
+ * conversion formula in mind (in matrix representation):
+ *
+ * | R/Cr |   | CC0 CC1 CC2 | | Cr/R |
+ * | G/Y  | = | CC3 CC4 CC5 | | Y /G |
+ * | B/Cb |   | CC6 CC7 CC8 | | Cb/B |
+ *
+ * Description: conversion coefficients setup
+ *
+ * @param [in] c0..c8 : coefficients from formula above
+ */
+otm_hdmi_ret_t hdmi_video_set_csc_012(hdmi_device_t *dev, float c0, float c1,
+                                       float c2);
+otm_hdmi_ret_t hdmi_video_set_csc_345(hdmi_device_t *dev, float c3, float c4,
+                                       float c5);
+otm_hdmi_ret_t hdmi_video_set_csc_678(hdmi_device_t *dev, float c6, float c7,
+                                       float c8);
+
+/*
+ * Description: conversion coefficients setup. Format details are specified
+ *             near each argument
+ *
+ * @param [in] c0..c8 : coefficients from folmula above (signed fixed point)
+ */
+otm_hdmi_ret_t hdmi_video_set_csc_012_fixed(hdmi_device_t *dev,
+                                       unsigned int c0,        /* 3.10 */
+                                       unsigned int c1,        /* 3.10 */
+                                       unsigned int c2);       /* 3.10 */
+otm_hdmi_ret_t hdmi_video_set_csc_345_fixed(hdmi_device_t *dev,
+                                       unsigned int c3,        /* 3.10 */
+                                       unsigned int c4,        /* 3.10 */
+                                       unsigned int c5);       /* 3.10 */
+otm_hdmi_ret_t hdmi_video_set_csc_678_fixed(hdmi_device_t *dev,
+                                       unsigned int c6,        /* 3.10 */
+                                       unsigned int c7,        /* 3.10 */
+                                       unsigned int c8);       /* 3.10 */
+
+/*
+ * Description: Programs htotal/hblank values. See EAS for details as
+ *              to how exactly to program these values
+ */
+otm_hdmi_ret_t hdmi_video_set_tv_timings(hdmi_device_t *dev,
+                                       unsigned int hactive,
+                                       unsigned int hblank);
+
+/*
+ * Description: Programs VSYNC and HSYNC polarity bit of Video Output Format
+ *              Register
+ *
+ * @param [in] v : vertical polarity;   GDL_TRUE -positive,
+                                       GDL_FALSE -negative
+ * @param [in] h : horizontal polarity; GDL_TRUE -positive,
+                                       GDL_FALSE -negative
+ */
+otm_hdmi_ret_t hdmi_video_set_output_polarity(hdmi_device_t *dev,
+                                       bool v, bool h);
+
+/*
+ * Description: Controls settings of PP (pixel packing) bits in GCP packets
+ *
+ * @param [in] pp : GDL_FALSE - pp controlled phase is 0;
+ *                  GDL_TRUE  - pp controlled phase is 1;
+ */
+otm_hdmi_ret_t hdmi_video_set_gcp_packet_pp_bits(hdmi_device_t *dev,
+                                               bool pp);
+
+/*
+ * Description: Controls setting of CD (color depth) bits in GCP packet
+ *
+ * @param [in] cd : GDL_FALSE - cd bits are zero;
+ *                  GDL_TRUE  - cd bits depend on color depth settings;
+ */
+otm_hdmi_ret_t hdmi_video_set_gcp_packet_cd_bits(hdmi_device_t *dev,
+                                           bool cd);
+
+/*
+ * Description: Controls pixel data source
+ *
+ * @param [in] pipe : GDL_TRUE  - pixel data comes from the pipe
+ *                    GDL_FALSE - pixel data comes from the register
+ */
+otm_hdmi_ret_t hdmi_video_set_pixel_source(hdmi_device_t *dev,
+                                               bool pipe);
+
+/*
+ * Description: Sets the color of the fixed pixel source
+ *
+ * @param [in] color : lower 24 bits represent RGB / CrYCb data to be shown
+ */
+otm_hdmi_ret_t hdmi_video_set_pixel_color(hdmi_device_t *dev,
+                                               unsigned int color);
+
+/*
+ * hdmi_video_set_video_indicator()
+ *
+ * @param [in] on : GDL_TRUE  - enable video indicator bit
+ *                : GDL_FALSE - disable video indicator bit
+ */
+otm_hdmi_ret_t hdmi_video_set_video_indicator(hdmi_device_t *dev,
+                                               bool on);
+
+/*
+ * INTERRUPTS
+ *
+ * Interrupts listed in the enumeration represent actual bits to be written in
+ * in the Interrupt Control Register. As of now interrupt status register has
+ * the same layout and these value can be used directly to look for incoming
+ * interupts in the interrupt handler.
+ */
+
+/*
+ * Description: The following interrupts are avalable
+ */
+typedef enum {
+       /* Keys are loaded from SEC */
+       HDMI_INTERRUPT_HDCP_KEYS_READY = 0x00100000,
+       /* Ri is available (128th frame) */
+       HDMI_INTERRUPT_HDCP_RI = 0x00080000,
+       /* Pre Ri is available (127th frame) */
+       HDMI_INTERRUPT_HDCP_RI_PRE = 0x00040000,
+       /* Pi is available ( 16th frame) */
+       HDMI_INTERRUPT_HDCP_PI = 0x00020000,
+       /* Pre Pi is available ( 15th frame) */
+       HDMI_INTERRUPT_HDCP_PI_PRE = 0x00010000,
+       /* Encrypted frame is sent */
+       HDMI_INTERRUPT_HDCP_FRAME = 0x00008000,
+       /* M0 is available for SEC access */
+       HDMI_INTERRUPT_HDCP_M0 = 0x00004000,
+       /* R0 computation is done */
+       HDMI_INTERRUPT_HDCP_R0 = 0x00002000,
+       /* Key buffer is ready after reset */
+       HDMI_INTERRUPT_HDCP_KEY_BUFFER_RESET = 0x00001000,
+       /* HW has transmitted 192 bytes block */
+       HDMI_INTERRUPT_AUDIO_BLOCK_DONE = 0x00000100,
+       /* FIFO is emtpy */
+       HDMI_INTERRUPT_AUDIO_FIFO_UNDERFLOW = 0x00000080,
+       /*  DMA completed write to DST */
+       HDMI_INTERRUPT_DMA_DST_COMPLETE = 0x00000040,
+       /* DMA completed read from SRC */
+       HDMI_INTERRUPT_DMA_SRC_COMPLETE = 0x00000020,
+       /* I2C bus error */
+       HDMI_INTERRUPT_I2C_BUS_ERROR = 0x00000010,
+       /* Internal 64 bytes buffer is full */
+       HDMI_INTERRUPT_I2C_BUFFER_FULL = 0x00000008,
+       /* Current I2C transaction done */
+       HDMI_INTERRUPT_I2C_TRANSACTION_DONE = 0x00000004,
+       /* Detection of Hot Plug */
+       HDMI_INTERRUPT_HOTPLUG_DETECT = 0x00000001
+} hdmi_interrupt_t;
+
+/*
+ * Description: Enabling/disabling interrupts of interest.
+ *
+ * @param [in] mask : user provided mask with OR'ed hdmi_interrupt_t values
+ */
+otm_hdmi_ret_t hdmi_interrupts_set_mask(hdmi_device_t *dev,
+                                       unsigned int mask);
+
+/*
+ * Description: Reading current interrupts settings
+ *
+ * @param [in] mask : user provided mask to store current interupts settings
+ */
+otm_hdmi_ret_t hdmi_interrupts_get_mask(hdmi_device_t *dev,
+                                       unsigned int *mask);
+
+/*
+ * Description: Reading current interrupts status
+ *
+ * @param [in] mask : user provided buffer to store current interrupts status
+ */
+otm_hdmi_ret_t hdmi_interrupts_get_status(hdmi_device_t *dev,
+                                       unsigned int *mask);
+
+/*
+ * Description: Acknowledgement of given interrupts.
+ *
+ * @param [in] mask : user provided mask with OR'ed hdmi_interrupt_t values
+ */
+otm_hdmi_ret_t hdmi_interrupts_acknowledge(hdmi_device_t *dev,
+                                       unsigned int mask);
+
+/*
+ * I2C
+ *
+ * Model of use:
+ * - higher level uses hdmi_i2c_transaction_* and hdmi_i2c_buffer_* calls
+ *   to manipulate data and start/stop transfers
+ * - higher level is responsible for handling reads more than 64 bytes
+ */
+
+/*
+ * Description: HDMI I2C unit support the following transactions
+ */
+typedef enum {
+       HDMI_I2C_TRANSACTION_HDCP_READ,
+       HDMI_I2C_TRANSACTION_HDCP_READ_RI,
+       HDMI_I2C_TRANSACTION_HDCP_WRITE,
+       HDMI_I2C_TRANSACTION_EDID_READ
+} hdmi_i2c_transaction_type_t;
+
+/*
+ * Description: This structure describes I2C transaction
+ */
+typedef struct {
+       hdmi_i2c_transaction_type_t type;
+       unsigned int sp;
+       unsigned int offset;
+       unsigned int size;
+} hdmi_i2c_transaction_t;
+
+/*
+ * Description: Size of HW I2C buffer. Higher level routines should use this
+ *              constant when implementing reads larger than buffer size
+ */
+#define HDMI_I2C_BUFFER_SIZE 64
+
+/*
+ * Description: Initiates HW accelerated I2C transaction
+ *
+ * @param [in] transaction : pointer to transaction descriptor
+ */
+otm_hdmi_ret_t hdmi_i2c_transaction_start(hdmi_device_t *dev,
+                               hdmi_i2c_transaction_t *transaction);
+
+/*
+ * Description: Continues current transaction
+ */
+otm_hdmi_ret_t hdmi_i2c_transaction_continue(hdmi_device_t *dev);
+
+/*
+ * Description: Stops current transaction
+ */
+otm_hdmi_ret_t hdmi_i2c_transaction_stop(hdmi_device_t *dev);
+
+/*
+ * Description: Writes user supplied data into the internal i2c unit buffer
+ *              User supplies up to 8 consecutive bytes. This call is
+ *              responsible for positioning these bytes properly in the
+ *              internal i2c buffer.
+ *
+ *              The following data can be written into hdcp port: An [8 bytes],
+ *              Ainfo [1 byte] and Aksv  [5 bytes]. Keeping this in mind
+ *              supported write size is limited to 1, 5 and 8 bytes
+ *
+ *              Aksv should be provided as 5 consecutive bytes.
+ *              An should be provided as 8 bytes word
+ *
+ * @param [in] buffer : user supplied buffer with data
+ * @param [in] size   : size of content in user buffer
+ */
+otm_hdmi_ret_t hdmi_i2c_buffer_write(hdmi_device_t *dev,
+                               void *buffer, unsigned int size);
+
+/*
+ * Description: Reads data from internal i2c buffer into user specified location
+ *              Bytes are positioned in the user supplied buffer in the same
+ *              order they reside at the specified offset.
+ *
+ * @param [out] buffer : user supplied buffer for data
+ * @param [in]  size   : number of requested bytes; valid range is [1..64]
+ */
+otm_hdmi_ret_t hdmi_i2c_buffer_read(hdmi_device_t *dev,
+                              void *buffer, unsigned int size);
+
+/*
+ * Description: I2C speed
+ */
+typedef enum {HDMI_I2C_SPEED_100KBPS,
+       HDMI_I2C_SPEED_400KBPS
+} hdmi_i2c_speed_t;
+
+/*
+ * Description: Resets, configures and enables I2C unit.
+ *
+ * @param [in] speed : operation speed
+ */
+otm_hdmi_ret_t hdmi_i2c_enable(hdmi_device_t *dev, hdmi_i2c_speed_t speed);
+
+/*
+ * Description: Disables I2C unit.
+ */
+otm_hdmi_ret_t ipil_hdmi_i2c_disable(hdmi_device_t *dev);
+
+/*
+ * Description: Alters DDC bus speed
+ */
+otm_hdmi_ret_t hdmi_i2c_set_ddc_speed(hdmi_device_t *dev,
+                                       bool slow);
+
+/*
+ * Description: Gets I2C unit bus monitor
+ */
+otm_hdmi_ret_t hdmi_i2c_get_bus_monitor(hdmi_device_t *dev,
+                                       unsigned int *value);
+
+/*
+ * Description: Gets I2C unis status
+ */
+otm_hdmi_ret_t hdmi_i2c_get_status(hdmi_device_t *dev, unsigned int *status);
+
+/*
+ * Non HW accelerated I2C read
+ */
+otm_hdmi_ret_t hdmi_i2c_sw_read(hdmi_device_t *dev,
+                          hdmi_i2c_transaction_t *t, unsigned char *buffer);
+
+/*
+ * Non HW accelerated I2C write
+ */
+otm_hdmi_ret_t hdmi_i2c_sw_write(hdmi_device_t *dev,
+                           hdmi_i2c_transaction_t *t, unsigned char *buffer);
+
+/*
+ * Configure SCL line
+ */
+otm_hdmi_ret_t hdmi_hal_i2c_scl_line_config(hdmi_device_t *dev,
+                                               bool bool);
+
+/*
+ * Set SCL line
+ */
+otm_hdmi_ret_t hdmi_hal_i2c_scl_line_set(hdmi_device_t *dev, bool b);
+
+/*
+ * Set GCP line number and pixel offset in GCPLINE register.
+ */
+otm_hdmi_ret_t hdmi_hal_gcp_line_set(hdmi_device_t *dev, int line_no,
+                                                       int pel_off);
+
+/*
+ * Set / clear avmute flag in GCP  descriptor register.
+ */
+otm_hdmi_ret_t hdmi_hal_gcp_avmute_set(hdmi_device_t *dev,
+                                       bool flag);
+
+/*
+ * HDCP
+ */
+
+/*
+ * Description: Sets RND register of HDMI Tx
+ *
+ * @param [in] rnd : random 64 bits value
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_set_rnd(hdmi_device_t *dev, void *rnd);
+
+/*
+ * Description: Triggers computation of An
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_compute_an(hdmi_device_t *dev);
+
+/*
+ * Description: Reads An from the HDMI Tx
+ *
+ * @param [out] an : user supplied 64 bit buffer for An
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_get_an(hdmi_device_t *dev, void *an);
+
+/*
+ * Description: Writes An to the HDMI Tx
+ *
+ * @param [in] an : user supplied 64 bit buffer with An
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_set_an(hdmi_device_t *dev, void *an);
+
+/*
+ * Description: Writes HDMI Tx KSV
+ *
+ * @param [out] aksv : user supplied buffer with 40bit KSV
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_set_aksv(hdmi_device_t *dev, void *aksv);
+
+/*
+ * Description: Toggles REPEATER bit in HDMI Tx
+ *
+ * @param [in] repeater : GDL_TRUE - on, GDL_FALSE - off
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_set_repeater(hdmi_device_t *dev,
+                                       bool repeater);
+
+/*
+ * Descriptor: Loads BKSV into the HDMI Tx
+ *
+ * @param [in] bksv : user supplied buffer with BKSV
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_set_bksv(hdmi_device_t *dev, void *bksv);
+
+/*
+ * Descriptor: Triggers computation of M0, R0 and K0
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_compute_mrk(hdmi_device_t *dev);
+
+/*
+ * Description: Makes M0 available for SEC usage
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_push_m0(hdmi_device_t *dev);
+
+/*
+ * Description: Toggles ENCRYPTION bit in Tx
+ *
+ * @param [in] state : GDL_TRUE - on, GDL_FALSE - off
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_set_encryption(hdmi_device_t *dev,
+                                               bool state);
+
+/*
+ * Description: Queries current state of ENCRYPTION bit in Tx
+ *
+ * @param [out] state : GDL_TRUE - on, GDL_FALSE - off
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_get_encryption(hdmi_device_t *dev,
+                                       bool *state);
+
+/*
+ * Description: Toggles AUTHENTICATON_STATE bit in Tx
+ *
+ * @param [in] state : GDL_TRUE - on, GDL_FALSE - off
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_set_auth(hdmi_device_t *dev, bool state);
+
+/*
+ * Description: Toggles 1.1_FEATURES bit in Tx
+ *
+ * @param [in] state : GDL_TRUE - on, GDL_FALSE - off
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_set_1p1_features(hdmi_device_t *dev,
+                                               bool state);
+
+/*
+ * Description: Toggles EESS bit in Tx
+ *
+ * @param [in] state : GDL_TRUE - on, GDL_FALSE - off
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_set_eess(hdmi_device_t *dev, bool state);
+
+/*
+ * Description: Toggles OESS bit in Tx
+ *
+ * @param [in] state : GDL_TRUE - on, GDL_FALSE - off
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_set_oess(hdmi_device_t *dev, bool state);
+
+/*
+ * Description: Toggles RING_CIPHER bit in Tx
+ *
+ * @param [in] state : GDL_TRUE - on, GDL_FALSE - off
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_set_rc(hdmi_device_t *dev, bool state);
+
+/*
+ * Description: Reads Ri from Tx
+ *
+ * @param [out] r : user supplied buffer for Ri
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_get_r(hdmi_device_t *dev, unsigned int *r);
+otm_hdmi_ret_t hdmi_hdcp_tx_get_r_pre(hdmi_device_t *dev, unsigned int *r_pre);
+
+/*
+ * Description: Reads Pi from Tx
+ *
+ * @param [out] p : user supplied buffer for Pi
+ */
+otm_hdmi_ret_t hdmi_hdcp_tx_get_p(hdmi_device_t *dev, unsigned int *p);
+otm_hdmi_ret_t hdmi_hdcp_tx_get_p_pre(hdmi_device_t *dev, unsigned int *p_pre);
+
+/*
+ * Description: Clears M0, R0 and An related triggers
+ */
+otm_hdmi_ret_t hdmi_hdcp_reset_triggers(hdmi_device_t *dev);
+
+/*
+ * OTHER STUFF
+ */
+
+/*
+ * Description: Querying of unit status register
+ */
+otm_hdmi_ret_t hdmi_general_get_status(hdmi_device_t *dev,
+                                       unsigned int *status);
+
+/*
+ * Description: Enable/disable analog portion of HDMI phy
+ */
+otm_hdmi_ret_t hdmi_phy_enable(hdmi_device_t *dev, bool enable);
+
+/*
+ * Description: Set equalization
+ */
+otm_hdmi_ret_t hdmi_phy_set_equalization(hdmi_device_t *dev,
+                                   otm_hdmi_equalize_t eq1,
+                                   otm_hdmi_equalize_t eq2);
+
+/*
+ * Description: Set transmit level
+ */
+otm_hdmi_ret_t hdmi_phy_set_transmit_level(hdmi_device_t *dev,
+                                     otm_hdmi_transmit_level_t tl1,
+                                     otm_hdmi_transmit_level_t tl2);
+
+/*
+ * Description: Set termination
+ */
+otm_hdmi_ret_t hdmi_phy_set_termination(hdmi_device_t *dev,
+                                  otm_hdmi_termination_t t1,
+                                  otm_hdmi_termination_t t2);
+
+/*
+ * Description: Set Current Adjustment
+ */
+otm_hdmi_ret_t hdmi_phy_set_current(hdmi_device_t *dev,
+                               otm_hdmi_current_t c1,
+                               otm_hdmi_current_t c2);
+
+/*
+ * Description: Set band gap level
+ */
+otm_hdmi_ret_t hdmi_phy_set_bglvl(hdmi_device_t *dev, otm_hdmi_bglvl_t t);
+
+/*
+ * Description: Alternates between sending real signal and dummy pattern
+ */
+otm_hdmi_ret_t hdmi_misc_set_output(hdmi_device_t *dev, bool output);
+
+#endif /* __HDMI_HAL_H__*/
diff --git a/drivers/staging/mrst/drv/otm_hdmi/ipil/include/ipil_hdcp_api.h b/drivers/staging/mrst/drv/otm_hdmi/ipil/include/ipil_hdcp_api.h
new file mode 100644 (file)
index 0000000..d504786
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef IPIL_HDCP_API_H
+#define IPIL_HDCP_API_H
+
+
+#include <linux/types.h>
+#include "hdmi_internal.h"
+
+extern bool ipil_hdcp_init(void);
+extern bool ipil_hdcp_is_ready(void);
+extern bool ipil_hdcp_get_an(uint8_t *an, uint32_t size);
+extern bool ipil_hdcp_get_aksv(uint8_t *aksv, uint32_t size);
+extern bool ipil_hdcp_set_repeater(bool present);
+extern bool ipil_hdcp_set_bksv(uint8_t *bksv);
+extern bool ipil_hdcp_start_authentication(void);
+extern bool ipil_hdcp_is_r0_ready(void);
+extern bool ipil_hdcp_does_ri_match(uint16_t rx_ri);
+extern bool ipil_hdcp_enable_encryption(void);
+extern bool ipil_hdcp_disable(void);
+extern bool ipil_hdcp_device_can_authenticate(void);
+
+#endif /* IPIL_HDCP_API_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/ipil/include/ipil_hdmi.h b/drivers/staging/mrst/drv/otm_hdmi/ipil/include/ipil_hdmi.h
new file mode 100644 (file)
index 0000000..843e73f
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef __IPIL_HDMI_H
+#define __IPIL_HDMI_H
+
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include "otm_hdmi.h"
+
+#include "hdmi_internal.h"
+#include "hdmi_hal.h"
+
+#define PCI_VENDOR_INTEL 0x8086
+#define PCI_RESOURCE_REGISTERS  0
+#define IPIL_MIN_PIXEL_CLOCK IPS_MIN_PIXEL_CLOCK
+#define IPIL_MAX_PIXEL_CLOCK IPS_MAX_PIXEL_CLOCK
+#define IPIL_PREFERRED_HDISPLAY IPS_PREFERRED_HDISPLAY
+#define IPIL_PREFERRED_VDISPLAY IPS_PREFERRED_VDISPLAY
+#define IPIL_PREFERRED_REFRESH_RATE IPS_PREFERRED_REFRESH_RATE
+
+
+otm_hdmi_ret_t ipil_hdmi_set_hdmi_dev(hdmi_device_t *dev);
+
+otm_hdmi_ret_t ipil_hdmi_decide_I2C_HW(hdmi_context_t *ctx);
+
+/*
+ * Description: Enable/disable assertion of 5V signal
+ */
+otm_hdmi_ret_t ipil_hdmi_general_5V_enable(hdmi_device_t *dev);
+otm_hdmi_ret_t ipil_hdmi_general_5V_disable(hdmi_device_t *dev);
+
+otm_hdmi_ret_t ipil_hdmi_set_program_clocks(hdmi_context_t *ctx,
+                                       unsigned int dclk);
+
+/*
+ * Description: Initialize/Deinitialize audio
+ */
+otm_hdmi_ret_t ipil_hdmi_audio_init(hdmi_context_t *ctx);
+otm_hdmi_ret_t ipil_hdmi_audio_deinit(hdmi_context_t *ctx);
+
+/* Description: Enable/disable HDCP clock. When HDCP clock is disabled
+ * unencrypted data can still be transmitted
+ */
+otm_hdmi_ret_t ipil_hdmi_general_hdcp_clock_enable(hdmi_device_t *dev);
+otm_hdmi_ret_t ipil_hdmi_general_hdcp_clock_disable(hdmi_device_t *dev);
+
+/*
+ * Description: Enable/disable audio and infoframe handling logic. This is
+ * useful when operating in DVI mode
+ */
+otm_hdmi_ret_t ipil_hdmi_general_audio_clock_enable(hdmi_device_t *dev);
+otm_hdmi_ret_t ipil_hdmi_general_audio_clock_disable(hdmi_device_t *dev);
+
+/*
+ * Description: Enable/disable pixel data path from VDC.
+ */
+otm_hdmi_ret_t ipil_hdmi_general_pixel_clock_enable(hdmi_device_t *dev);
+otm_hdmi_ret_t ipil_hdmi_general_pixel_clock_disable(hdmi_device_t *dev);
+
+/*
+ * Description: Enable/disable TDMS clock, i.e. output path from Tx is off and
+ * hence unit is off.
+ */
+otm_hdmi_ret_t ipil_hdmi_general_tdms_clock_enable(hdmi_device_t *dev);
+otm_hdmi_ret_t ipil_hdmi_general_tdms_clock_disable(hdmi_device_t *dev);
+
+/*
+ * Description: Enable/disable HDMI unit
+ */
+otm_hdmi_ret_t ipil_hdmi_general_unit_enable(hdmi_device_t *dev);
+otm_hdmi_ret_t ipil_hdmi_general_unit_disable(hdmi_device_t *dev);
+
+/*
+ * Description: Turn HDMI power rails on
+ */
+bool ipil_hdmi_power_rails_on();
+
+/*
+ * Description: hdmi interrupt handler (upper half).
+ *             handles the interrupts by reading hdmi status register
+ *             and waking up bottom half if needed.
+ *
+ * @dev:       hdmi_device_t
+ *
+ * Returns:    IRQ_HANDLED on NULL input arguments, and if the
+ *                     interrupt is not HDMI HPD interrupts.
+ *             IRQ_WAKE_THREAD if this is a HDMI HPD interrupt.
+ */
+irqreturn_t ipil_hdmi_irq_handler(hdmi_device_t *dev);
+
+/*
+ * Description: programs hdmi pipe src and size of the input.
+ *
+ * @dev:               hdmi_device_t
+ * @scalingtype:       scaling type (FULL_SCREEN, CENTER, NO_SCALE etc.)
+ * @mode:              mode requested
+ * @adjusted_mode:     adjusted mode
+ * @fb_width, fb_height:allocated frame buffer dimensions
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t ipil_hdmi_crtc_mode_set_program_dspregs(hdmi_device_t *dev,
+                                       int scalingtype,
+                                       ipil_timings_t *mode,
+                                       ipil_timings_t *adjusted_mode,
+                                       int fb_width, int fb_height);
+
+/*
+ * Description: this is pre-modeset configuration. This can be
+ *             resetting HDMI unit, disabling/enabling dpll etc
+ *             on the need basis.
+ *
+ * @dev:       hdmi_device_t
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t ipil_hdmi_crtc_mode_set_prepare(hdmi_device_t *dev);
+
+/*
+ * Description: programs all the timing registers based on scaling type.
+ *
+ * @dev:               hdmi_device_t
+ * @scalingtype:       scaling type (FULL_SCREEN, CENTER, NO_SCALE etc.)
+ * @mode:              mode requested
+ * @adjusted_mode:     adjusted mode
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t ipil_hdmi_crtc_mode_set_program_timings(hdmi_device_t *dev,
+                                       int scalingtype,
+                                       otm_hdmi_timing_t *mode,
+                                       otm_hdmi_timing_t *adjusted_mode);
+
+/*
+ * Description: programs dpll clocks, enables dpll and waits
+ *             till it locks with DSI PLL
+ *
+ * @dev:       hdmi_device_t
+ * @dclk:      refresh rate dot clock in kHz of current mode
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t ipil_hdmi_crtc_mode_set_program_dpll(hdmi_device_t *dev,
+                                                       unsigned long dclk);
+
+/*
+ * Description: configures the display plane register and enables
+ *             pipeconf.
+ *
+ * @dev: hdmi_device_t
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t ipil_hdmi_crtc_mode_set_program_pipeconf(hdmi_device_t *dev);
+
+otm_hdmi_ret_t ipil_hdmi_enable_infoframe(hdmi_device_t *dev,
+                                       unsigned int type,
+                                       otm_hdmi_packet_t *pkt,
+                                       unsigned int freq);
+
+otm_hdmi_ret_t ipil_hdmi_disable_infoframe(hdmi_device_t *dev,
+                                       unsigned int type);
+
+otm_hdmi_ret_t ipil_hdmi_disable_all_infoframes(hdmi_device_t *dev);
+
+/*
+ * Description: encoder mode set function for hdmi. enables phy.
+ *             set correct polarity for the current mode, sets
+ *             correct panel fitting.
+ *
+ *
+ * @dev:               hdmi_device_t
+ * @mode:              mode requested
+ * @adjusted_mode:     adjusted mode
+ * @is_monitor_hdmi:   is monitor type is hdmi or not
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t ipil_hdmi_enc_mode_set(hdmi_device_t *dev,
+                                       otm_hdmi_timing_t *mode,
+                                       otm_hdmi_timing_t *adjusted_mode,
+                                       bool is_monitor_hdmi);
+/*
+ * Description: save HDMI display registers
+ *
+ * @dev:        hdmi_device_t
+ *
+ * Returns: none
+ */
+void ipil_hdmi_save_display_registers(hdmi_device_t *dev);
+void ipil_hdmi_save_data_island(hdmi_device_t *dev);
+
+/*
+ * Description: restore HDMI display registers and enable display
+ *
+ * @dev:        hdmi_device_t
+ *
+ * Returns: none
+ */
+void ipil_hdmi_restore_and_enable_display(hdmi_device_t *dev);
+void ipil_hdmi_restore_data_island(hdmi_device_t *dev);
+
+/*
+ * Description: destroys any saved HDMI data
+ *
+ * @dev:       hdmi_device_t
+ *
+ * Returns: none
+ */
+void ipil_hdmi_destroy_saved_data(hdmi_device_t *dev);
+
+/*
+ * Description: disable HDMI display
+ *
+ * @dev:        hdmi_device_t
+ *
+ * Returns: none
+ */
+void ipil_disable_hdmi(hdmi_device_t *dev);
+
+#endif /* __IPIL_HDMI_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/ipil/specific/include/ips_hdcp_api.h b/drivers/staging/mrst/drv/otm_hdmi/ipil/specific/include/ips_hdcp_api.h
new file mode 100644 (file)
index 0000000..3b94b02
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+
+#ifndef IPS_HDCP_API_H
+#define IPS_HDCP_API_H
+
+
+#include <linux/types.h>
+
+extern bool ips_hdcp_init(void);
+extern bool ips_hdcp_is_ready(void);
+extern void ips_hdcp_off(void);
+
+extern void ips_hdcp_get_an(uint8_t *an);
+extern void ips_hdcp_get_aksv(uint8_t *aksv);
+extern bool ips_hdcp_set_bksv(uint8_t *bksv);
+extern bool ips_hdcp_is_r0_ready(void);
+extern bool ips_hdcp_set_repeater(bool present);
+extern bool ips_hdcp_start_authentication(void);
+extern bool ips_hdcp_enable_encryption(void);
+extern bool ips_hdcp_does_ri_match(uint16_t rx_ri);
+extern bool ips_hdcp_disable(void);
+extern bool ips_hdcp_device_can_authenticate(void);
+
+#endif /* IPS_HDCP_API_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/ipil/specific/include/ips_hdmi.h b/drivers/staging/mrst/drv/otm_hdmi/ipil/specific/include/ips_hdmi.h
new file mode 100644 (file)
index 0000000..5f446b9
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef __IPS_HDMI_H
+#define __IPS_HDMI_H
+
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include "otm_hdmi_types.h"
+#include "hdmi_internal.h"
+
+/* FIXME: Make them IP specific */
+#define PCI_DEVICE_HDMI 0x080D
+#define PCI_LENGTH_HDMI 0x7000
+#define IPS_MIN_PIXEL_CLOCK 25175
+#define IPS_MAX_PIXEL_CLOCK 74250
+#define IPS_PREFERRED_HDISPLAY 1920
+#define IPS_PREFERRED_VDISPLAY 1080
+#define IPS_PREFERRED_REFRESH_RATE 30
+
+/* TODO: revisit these. make them IP specific */
+#define IPS_DPLL_B           (0x0f018)
+#define IPS_DPLL_DIV0        (0x0f048)
+#define IPS_PIPEBCONF        (0x71008)
+#define IPS_HTOTAL_B         (0x61000)
+#define IPS_HBLANK_B         (0x61004)
+#define IPS_HSYNC_B          (0x61008)
+#define IPS_VTOTAL_B         (0x6100c)
+#define IPS_VBLANK_B         (0x61010)
+#define IPS_VSYNC_B          (0x61014)
+#define IPS_PIPEBSRC         (0x6101c)
+#define IPS_DSPBSTRIDE       (0x71188)
+#define IPS_DSPBLINOFF       (0X71184)
+#define IPS_DSPBTILEOFF      (0x711A4)
+#define IPS_DSPBSIZE         (0x71190)
+#define IPS_DSPBPOS          (0x7118C)
+#define IPS_DSPBSURF         (0x7119C)
+#define IPS_DSPBCNTR         (0x71180)
+#define IPS_DSPBSTAT         (0x71024)
+#define IPS_PALETTE_B        (0x0a800)
+#define IPS_PFIT_CONTROL     (0x61230)
+#define IPS_PFIT_PGM_RATIOS  (0x61234)
+#define IPS_HDMIPHYMISCCTL   (0x61134)
+#define IPS_HDMIB_CONTROL    (0x61140)
+#define IPS_PFIT_ENABLE                (1 << 31)
+
+otm_hdmi_ret_t ips_hdmi_decide_I2C_HW(hdmi_context_t *ctx);
+
+otm_hdmi_ret_t ips_hdmi_general_5V_enable(hdmi_device_t *dev);
+
+otm_hdmi_ret_t ips_hdmi_general_5V_disable(hdmi_device_t *dev);
+
+otm_hdmi_ret_t ips_hdmi_set_program_clocks(hdmi_context_t *ctx,
+                                       unsigned int dclk);
+
+otm_hdmi_ret_t ips_hdmi_audio_init(hdmi_context_t *ctx);
+
+otm_hdmi_ret_t ips_hdmi_audio_deinit(hdmi_context_t *ctx);
+
+otm_hdmi_ret_t ips_hdmi_general_unit_enable(hdmi_device_t *dev);
+
+otm_hdmi_ret_t ips_hdmi_general_unit_disable(hdmi_device_t *dev);
+
+otm_hdmi_ret_t ips_hdmi_general_hdcp_clock_enable(hdmi_device_t *dev);
+
+otm_hdmi_ret_t ips_hdmi_general_hdcp_clock_disable(hdmi_device_t *dev);
+
+otm_hdmi_ret_t ips_hdmi_general_audio_clock_enable(hdmi_device_t *dev);
+
+otm_hdmi_ret_t ips_hdmi_general_audio_clock_disable(hdmi_device_t *dev);
+
+otm_hdmi_ret_t ips_hdmi_general_pixel_clock_enable(hdmi_device_t *dev);
+
+otm_hdmi_ret_t ips_hdmi_general_pixel_clock_disable(hdmi_device_t *dev);
+
+otm_hdmi_ret_t ips_hdmi_general_tdms_clock_enable(hdmi_device_t *dev);
+
+otm_hdmi_ret_t ips_hdmi_general_tdms_clock_disable(hdmi_device_t *dev);
+
+otm_hdmi_ret_t ips_hdmi_i2c_disable(hdmi_device_t *dev);
+
+bool ips_hdmi_power_rails_on();
+
+irqreturn_t ips_hdmi_irq_handler(void *io_address);
+
+otm_hdmi_ret_t ips_hdmi_disable_vid_infoframe(hdmi_device_t *dev,
+                                       unsigned int type);
+
+otm_hdmi_ret_t ips_hdmi_enable_vid_infoframe(hdmi_device_t *dev,
+                                       unsigned int type,
+                                       otm_hdmi_packet_t *pkt,
+                                       unsigned int freq);
+
+otm_hdmi_ret_t ips_hdmi_disable_all_infoframes(hdmi_device_t *dev);
+
+/*
+ * Description: gets the best dpll clock value based on
+ *             current timing mode clock.
+ *
+ * @clk:               refresh rate dot clock in kHz of current mode
+ * @pdpll, pfp:                will be set to adjusted dpll values.
+ * @pclock_khz:                tmds clk value for the best pll and is needed for audio.
+ *                     This field has to be moved into OTM audio
+ *                     interfaces when implemented
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments.
+ */
+otm_hdmi_ret_t ips_hdmi_get_adjusted_clk(unsigned long clk,
+                               u32 *pdpll, u32 *pfp, uint32_t *pclock_khz);
+
+/*
+ * Description: restore HDMI display registers and enable display
+ *
+ * @dev:        hdmi_device_t
+ *
+ * Returns: none
+ */
+void ips_hdmi_restore_and_enable_display(hdmi_device_t *dev);
+void ips_hdmi_restore_data_island(hdmi_device_t *dev);
+
+/*
+ * Description: save HDMI display registers
+ *
+ * @dev:        hdmi_device_t
+ *
+ * Returns: none
+ */
+void ips_hdmi_save_display_registers(hdmi_device_t *dev);
+void ips_hdmi_save_data_island(hdmi_device_t *dev);
+
+/*
+ * Description: destroys any saved HDMI data
+ *
+ * @dev:        hdmi_device_t
+ *
+ * Returns: none
+ */
+void ips_hdmi_destroy_saved_data(hdmi_device_t *dev);
+
+/*
+ * Description: disable HDMI display
+ *
+ * @dev:        hdmi_device_t
+ *
+ * Returns: none
+ */
+void ips_disable_hdmi(hdmi_device_t *dev);
+#endif /* __IPS_HDMI_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/ipil/specific/mfld/ips_hdcp.c b/drivers/staging/mrst/drv/otm_hdmi/ipil/specific/mfld/ips_hdcp.c
new file mode 100644 (file)
index 0000000..d2426f7
--- /dev/null
@@ -0,0 +1,369 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+
+#include <linux/types.h>
+#include <linux/delay.h>
+#include "hdcp_rx_defs.h"
+#include "mfld_hdcp_reg.h"
+#include "mfld_utils.h"
+
+static void ips_hdcp_capture_an(void);
+static bool ips_hdcp_is_hdcp_on(void);
+static bool ips_hdcp_is_an_ready(void);
+static void ips_hdcp_read_an(uint8_t *an);
+static void ips_hdcp_write_rx_ri(uint16_t rx_ri);
+static void ips_hdcp_set_config(int val);
+static int ips_hdcp_get_config(void);
+static bool ips_hdcp_is_encrypting(void);
+static uint8_t ips_hdcp_get_repeater_control(void);
+static void ips_hdcp_set_repeater_control(int value);
+static uint8_t ips_hdcp_get_repeater_status(void);
+static int ips_hdcp_repeater_v_match_check(void);
+static bool ips_hdcp_repeater_is_busy(void);
+static int ips_hdcp_repeater_rdy_for_nxt_data(void);
+
+static uint32_t ips_hdcp_get_status(void)
+{
+       return hdmi_read32(MDFLD_HDCP_STATUS_REG);
+}
+
+static void ips_hdcp_enable_port(bool enable)
+{
+       uint32_t hdmib_reg = hdmi_read32(MDFLD_HDMIB_CNTRL_REG);
+       if (enable)
+               hdmib_reg |= MDFLD_HDMIB_HDCP_PORT_SEL;
+       else
+               hdmib_reg &= ~MDFLD_HDMIB_HDCP_PORT_SEL;
+       hdmi_write32(MDFLD_HDMIB_CNTRL_REG, hdmib_reg);
+}
+
+static void ips_hdcp_capture_an(void)
+{
+       hdmi_write32(MDFLD_HDCP_INIT_REG, (uint32_t) jiffies);
+       hdmi_write32(MDFLD_HDCP_INIT_REG, (uint32_t) (jiffies >> 1));
+       hdmi_write32(MDFLD_HDCP_CONFIG_REG, HDCP_CAPTURE_AN);
+}
+
+static bool ips_hdcp_is_hdcp_on(void)
+{
+       struct ips_hdcp_status_reg_t status;
+       status.value = ips_hdcp_get_status();
+
+       if (status.hdcp_on)
+               return true;
+
+       return false;
+}
+
+static bool ips_hdcp_is_an_ready(void)
+{
+       struct ips_hdcp_status_reg_t status;
+       status.value = ips_hdcp_get_status();
+
+       if (status.an_ready)
+               return true;
+
+       return false;
+}
+
+static void ips_hdcp_read_an(uint8_t *an)
+{
+       uint8_t i = 0;
+       struct double_word_t temp;
+       temp.value = 0;
+       temp.low = hdmi_read32(MDFLD_HDCP_AN_LOW_REG);
+       temp.high = hdmi_read32(MDFLD_HDCP_AN_HI_REG);
+       for (i = 0; i < HDCP_AN_SIZE; i++)
+               an[i] = temp.byte[i];
+}
+
+static void ips_hdcp_write_rx_ri(uint16_t rx_ri)
+{
+       hdmi_write32(MDFLD_HDCP_RECEIVER_RI_REG, rx_ri);
+}
+
+static void ips_hdcp_set_config(int val)
+{
+       struct ips_hdcp_config_reg_t config;
+       config.value = hdmi_read32(MDFLD_HDCP_CONFIG_REG);
+       config.hdcp_config = val;
+       hdmi_write32(MDFLD_HDCP_CONFIG_REG, config.value);
+}
+
+static int ips_hdcp_get_config(void)
+{
+       struct ips_hdcp_config_reg_t config;
+       config.value = hdmi_read32(MDFLD_HDCP_CONFIG_REG);
+       return config.hdcp_config;
+}
+
+static bool ips_hdcp_config_is_encrypting(void)
+{
+       if (ips_hdcp_get_config() == HDCP_AUTHENTICATE_AND_ENCRYPT)
+               return true;
+       return false;
+}
+
+static bool ips_hdcp_is_encrypting(void)
+{
+       struct ips_hdcp_status_reg_t status;
+       status.value = ips_hdcp_get_status();
+
+       if (status.encrypting)
+               return true;
+
+       return false;
+}
+
+static uint8_t ips_hdcp_get_repeater_control(void)
+{
+       struct ips_hdcp_repeater_reg_t repeater;
+       repeater.value = hdmi_read32(MDFLD_HDCP_REP_REG);
+       return repeater.control;
+}
+
+static void ips_hdcp_set_repeater_control(int value)
+{
+       struct ips_hdcp_repeater_reg_t repeater;
+       repeater.value = hdmi_read32(MDFLD_HDCP_REP_REG);
+       repeater.control = value;
+       hdmi_write32(MDFLD_HDCP_REP_REG, repeater.value);
+}
+
+static uint8_t ips_hdcp_get_repeater_status(void)
+{
+       struct ips_hdcp_repeater_reg_t repeater;
+       repeater.value = hdmi_read32(MDFLD_HDCP_REP_REG);
+       return repeater.status;
+}
+
+static int ips_hdcp_repeater_v_match_check(void)
+{
+       uint8_t status = ips_hdcp_get_repeater_status();
+       switch (status) {
+       case HDCP_REPEATER_STATUS_COMPLETE_MATCH:
+               return 1;
+       case HDCP_REPEATER_STATUS_BUSY:
+               return -1;
+       default:
+               return 0;
+       }
+}
+
+static bool ips_hdcp_repeater_is_busy(void)
+{
+       uint8_t status = ips_hdcp_get_repeater_status();
+       if (status == HDCP_REPEATER_STATUS_BUSY)
+               return true;
+       return false;
+}
+
+static int ips_hdcp_repeater_rdy_for_nxt_data(void)
+{
+       uint8_t status = ips_hdcp_get_repeater_status();
+       if (status == HDCP_REPEATER_STATUS_RDY_NEXT_DATA)
+               return true;
+       return false;
+}
+
+bool ips_hdcp_is_ready(void)
+{
+       struct ips_hdcp_status_reg_t status;
+       status.value = ips_hdcp_get_status();
+
+       if (status.fus_success && status.fus_complete)
+               return true;
+
+       return false;
+}
+
+void ips_hdcp_off(void)
+{
+       ips_hdcp_set_config(HDCP_Off);
+       msleep(30);
+}
+
+void ips_hdcp_get_an(uint8_t *an)
+{
+       bool ret = false;
+       ips_hdcp_off();
+       ips_hdcp_capture_an();
+       do {
+               ret = ips_hdcp_is_an_ready();
+       } while  (ret == false);
+       ips_hdcp_read_an(an);
+}
+
+void ips_hdcp_get_aksv(uint8_t *aksv)
+{
+       static uint8_t save_aksv[HDCP_KSV_SIZE] = {0, 0, 0, 0, 0};
+       static bool aksv_read_once = false;
+       uint8_t i = 0;
+       struct double_word_t temp;
+       if (aksv_read_once == false) {
+               temp.value = 0;
+               temp.low = hdmi_read32(MDFLD_HDCP_AKSV_LOW_REG);
+               temp.high = hdmi_read32(MDFLD_HDCP_AKSV_HI_REG);
+               aksv_read_once = true;
+               for (i = 0; i < HDCP_KSV_SIZE; i++)
+                       save_aksv[i] = temp.byte[i];
+       }
+       for (i = 0; i < HDCP_KSV_SIZE; i++)
+               aksv[i] = save_aksv[i];
+}
+
+bool ips_hdcp_set_bksv(uint8_t *bksv)
+{
+       uint8_t i = 0;
+       struct double_word_t temp;
+       if (bksv == NULL)
+               return false;
+       temp.value = 0;
+       for (i = 0; i < HDCP_KSV_SIZE; i++)
+               temp.byte[i] = bksv[i];
+
+       hdmi_write32(MDFLD_HDCP_BKSV_LOW_REG, temp.low);
+       hdmi_write32(MDFLD_HDCP_BKSV_HI_REG, temp.high);
+       return true;
+}
+
+bool ips_hdcp_set_repeater(bool present)
+{
+       struct ips_hdcp_repeater_reg_t repeater;
+       repeater.value = hdmi_read32(MDFLD_HDCP_REP_REG);
+       repeater.present = present;
+       hdmi_write32(MDFLD_HDCP_REP_REG, repeater.value);
+       return true;
+}
+
+bool ips_hdcp_start_authentication(void)
+{
+       ips_hdcp_enable_port(true);
+       ips_hdcp_set_config(HDCP_AUTHENTICATE_AND_ENCRYPT);
+       return true;
+}
+
+bool ips_hdcp_is_r0_ready(void)
+{
+       struct ips_hdcp_status_reg_t status;
+       status.value = ips_hdcp_get_status();
+
+       if (status.ri_ready) {
+               /* Set Ri to 0 */
+               ips_hdcp_write_rx_ri(0);
+               /* Set Repeater to Not Present */
+               ips_hdcp_set_repeater(0);
+               return true;
+       }
+       return false;
+}
+
+bool ips_hdcp_enable_encryption(void)
+{
+       struct ips_hdcp_status_reg_t status;
+       uint32_t hdmib_reg = hdmi_read32(MDFLD_HDMIB_CNTRL_REG);
+       status.value = ips_hdcp_get_status();
+
+       if (ips_hdcp_is_hdcp_on() &&
+           ips_hdcp_config_is_encrypting() &&
+           status.ri_match &&
+           (hdmib_reg & MDFLD_HDMIB_HDCP_PORT_SEL))
+               return true;
+       return false;
+}
+
+
+bool ips_hdcp_does_ri_match(uint16_t rx_ri)
+{
+       struct ips_hdcp_status_reg_t status;
+
+       ips_hdcp_write_rx_ri(rx_ri);
+       status.value = ips_hdcp_get_status();
+       if (status.ri_match)
+               return true;
+       return false;
+}
+
+bool ips_hdcp_disable(void)
+{
+       ips_hdcp_off();
+       /* Set Rx_Ri to 0 */
+       ips_hdcp_write_rx_ri(0);
+       /* Set Repeater to Not Present */
+       ips_hdcp_set_repeater(false);
+       /* Disable HDCP on this Port */
+       /* ips_hdcp_enable_port(false); */
+       return true;
+}
+
+bool ips_hdcp_init(void)
+{
+       return true;
+}
+
+bool ips_hdcp_device_can_authenticate(void)
+{
+       return true;
+}
+
diff --git a/drivers/staging/mrst/drv/otm_hdmi/ipil/specific/mfld/ips_hdmi.c b/drivers/staging/mrst/drv/otm_hdmi/ipil/specific/mfld/ips_hdmi.c
new file mode 100644 (file)
index 0000000..cc879e3
--- /dev/null
@@ -0,0 +1,815 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+
+#include <asm/io.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+
+#include "otm_hdmi.h"
+#include "hdmi_internal.h"
+#include "ips_hdmi.h"
+#include "mfld_hdmi_reg.h"
+#include "ipil_internal.h"
+#include "mfld_utils.h"
+
+static unsigned char vrint_data;
+
+otm_hdmi_ret_t ips_hdmi_decide_I2C_HW(hdmi_context_t *ctx)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+otm_hdmi_ret_t ips_hdmi_general_5V_enable(hdmi_device_t *dev)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+otm_hdmi_ret_t ips_hdmi_general_5V_disable(hdmi_device_t *dev)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+otm_hdmi_ret_t ips_hdmi_set_program_clocks(hdmi_context_t *ctx,
+                                               unsigned int dclk)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+otm_hdmi_ret_t ips_hdmi_audio_init(hdmi_context_t *ctx)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+otm_hdmi_ret_t ips_hdmi_audio_deinit(hdmi_context_t *ctx)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+otm_hdmi_ret_t ips_hdmi_general_unit_enable(hdmi_device_t *dev)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+otm_hdmi_ret_t ips_hdmi_general_unit_disable(hdmi_device_t *dev)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+otm_hdmi_ret_t ips_hdmi_general_hdcp_clock_enable(hdmi_device_t *dev)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+otm_hdmi_ret_t ips_hdmi_general_hdcp_clock_disable(hdmi_device_t *dev)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+otm_hdmi_ret_t ips_hdmi_general_audio_clock_enable(hdmi_device_t *dev)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+otm_hdmi_ret_t ips_hdmi_general_audio_clock_disable(hdmi_device_t *dev)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+otm_hdmi_ret_t ips_hdmi_general_pixel_clock_enable(hdmi_device_t *dev)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+otm_hdmi_ret_t ips_hdmi_general_pixel_clock_disable(hdmi_device_t *dev)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+otm_hdmi_ret_t ips_hdmi_general_tdms_clock_enable(hdmi_device_t *dev)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+otm_hdmi_ret_t ips_hdmi_general_tdms_clock_disable(hdmi_device_t *dev)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+otm_hdmi_ret_t ips_hdmi_i2c_disable(hdmi_device_t *dev)
+{
+       /* TODO: TO BE IMPLEMENTED */
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+bool ips_hdmi_power_rails_on()
+{
+       /* Turn on HDMI power rails. These will be on in all non-S0iX
+        * states so that HPD and connection status will work. VCC330
+        * will have ~1.7mW usage during idle states when the display
+        * is active
+        */
+       intel_scu_ipc_iowrite8(IPS_MSIC_VCC330CNT, IPS_VCC330_ON);
+
+       if (vrint_data & IPS_HDMI_OCP_STATUS) {
+               /* When there occurs overcurrent in MSIC HDMI HDP,
+                * need to reset VHDMIEN by clearing to 0 then set to 1
+                */
+               intel_scu_ipc_iowrite8(IPS_MSIC_VHDMICNT,
+                                       IPS_VHDMI_OFF);
+
+               /* MSIC documentation requires that there be a 500us
+                * delay after enabling VCC330 before you can enable
+                * VHDMI
+                */
+               usleep_range(500, 1000);
+
+               /* Extend VHDMI switch de-bounce time, to avoid
+                * redundant MSIC VREG/HDMI interrupt during HDMI
+                * cable plugged in/out
+                */
+               intel_scu_ipc_iowrite8(IPS_MSIC_VHDMICNT,
+                                       IPS_VHDMI_ON |
+                                       IPS_VHDMI_DB_30MS);
+       }
+
+       if (vrint_data & IPS_HDMI_HPD_STATUS_BIT)
+               return true;
+       return false;
+}
+
+irqreturn_t ips_hdmi_irq_handler(void *io_address)
+{
+       /* Read interrupt status register */
+       if (io_address != NULL) {
+               vrint_data = readb(io_address);
+
+               /* handle HDMI HPD interrupts. */
+               if (vrint_data & (IPS_HDMI_HPD_STATUS_BIT|IPS_HDMI_OCP_STATUS))
+                       return IRQ_WAKE_THREAD;
+       }
+       return IRQ_HANDLED;
+}
+
+otm_hdmi_ret_t ips_hdmi_disable_vid_infoframe(hdmi_device_t *dev,
+                                       unsigned int type)
+{
+       uint32_t vid_dip_ctl = 0;
+       uint32_t dip_type = 0;
+       uint32_t index = 0;
+
+       if (!dev)
+               return OTM_HDMI_ERR_NULL_ARG;
+
+       /* Enable Particular Packet Type */
+       switch (type) {
+       case HDMI_PACKET_AVI:
+               dip_type = IPS_HDMI_EN_DIP_TYPE_AVI;
+               index = IPS_HDMI_DIP_BUFF_INDX_AVI;
+               break;
+       case HDMI_PACKET_VS:
+               dip_type = IPS_HDMI_EN_DIP_TYPE_VS;
+               index = IPS_HDMI_DIP_BUFF_INDX_VS;
+               break;
+       case HDMI_PACKET_SPD:
+               dip_type = IPS_HDMI_EN_DIP_TYPE_SPD;
+               index = IPS_HDMI_DIP_BUFF_INDX_SPD;
+               break;
+       default:
+               return OTM_HDMI_ERR_INVAL;
+       }
+
+       /* Disable DIP type & set the buffer index & reset access address */
+       vid_dip_ctl = hdmi_read32(IPS_HDMI_VID_DIP_CTL_ADDR);
+       vid_dip_ctl &= ~(dip_type |
+                       IPS_HDMI_DIP_BUFF_INDX_MASK |
+                       IPS_HDMI_DIP_ACCESS_ADDR_MASK |
+                       IPS_HDMI_DIP_TRANSMISSION_FREQ_MASK);
+       vid_dip_ctl |= (index |
+                       IPS_HDMI_VID_PORT_B_SELECT |
+                       IPS_HDMI_VID_EN_DIP);
+       hdmi_write32(IPS_HDMI_VID_DIP_CTL_ADDR, vid_dip_ctl);
+
+       return OTM_HDMI_SUCCESS;
+}
+
+/* TODO: REVISIT FOR OPTIMIZATION */
+otm_hdmi_ret_t ips_hdmi_enable_vid_infoframe(hdmi_device_t *dev,
+               unsigned int type, otm_hdmi_packet_t *pkt, unsigned int freq)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       uint32_t vid_dip_ctl = 0;
+       uint32_t index = 0;
+       uint32_t dip_type = 0;
+       uint32_t dip_data = 0;
+
+       if (!dev || !pkt)
+               return OTM_HDMI_ERR_NULL_ARG;
+
+       if (freq > HDMI_DIP_SEND_ATLEAST_EVERY_OTHER_VSYNC)
+               return OTM_HDMI_ERR_INVAL;
+
+       rc = ips_hdmi_disable_vid_infoframe(dev, type);
+       if (rc != OTM_HDMI_SUCCESS)
+               return rc;
+
+       /* Add delay for any Pending transmissions ~ 2 VSync + 3 HSync */
+       msleep_interruptible(32 + 8);
+
+       /* Enable Particular Packet Type */
+       switch (type) {
+       case HDMI_PACKET_AVI:
+               dip_type = IPS_HDMI_EN_DIP_TYPE_AVI;
+               index = IPS_HDMI_DIP_BUFF_INDX_AVI;
+               break;
+       case HDMI_PACKET_VS:
+               dip_type = IPS_HDMI_EN_DIP_TYPE_VS;
+               index = IPS_HDMI_DIP_BUFF_INDX_VS;
+               break;
+       case HDMI_PACKET_SPD:
+               dip_type = IPS_HDMI_EN_DIP_TYPE_SPD;
+               index = IPS_HDMI_DIP_BUFF_INDX_SPD;
+               break;
+       default:
+               return OTM_HDMI_ERR_INVAL;
+       }
+
+       /* Disable DIP type & set the buffer index & reset access address */
+       vid_dip_ctl = hdmi_read32(IPS_HDMI_VID_DIP_CTL_ADDR);
+       vid_dip_ctl &= ~(dip_type |
+                       IPS_HDMI_DIP_BUFF_INDX_MASK |
+                       IPS_HDMI_DIP_ACCESS_ADDR_MASK |
+                       IPS_HDMI_DIP_TRANSMISSION_FREQ_MASK);
+       vid_dip_ctl |= (index |
+                       IPS_HDMI_VID_PORT_B_SELECT |
+                       IPS_HDMI_VID_EN_DIP);
+       hdmi_write32(IPS_HDMI_VID_DIP_CTL_ADDR, vid_dip_ctl);
+
+       /* Write Packet Data */
+       dip_data = 0;
+       dip_data = (pkt->header[0] << 0) |
+                  (pkt->header[1] << 8) |
+                  (pkt->header[2] << 16);
+       hdmi_write32(IPS_HDMI_VIDEO_DIP_DATA_ADDR, dip_data);
+
+       for (index = 0; index < (HDMI_DIP_PACKET_DATA_LEN/4); index++) {
+               dip_data = pkt->data32[index];
+               hdmi_write32(IPS_HDMI_VIDEO_DIP_DATA_ADDR, dip_data);
+       }
+
+       /* Enable Packet Type & Transmission Frequency */
+       vid_dip_ctl = hdmi_read32(IPS_HDMI_VID_DIP_CTL_ADDR);
+       vid_dip_ctl &= ~IPS_HDMI_VID_PORT_SELECT_MASK;
+       vid_dip_ctl |= (IPS_HDMI_VID_PORT_B_SELECT | IPS_HDMI_VID_EN_DIP);
+       vid_dip_ctl |= (dip_type | (freq << IPS_HDMI_DIP_TX_FREQ_SHIFT));
+       pr_debug("vid_dip_ctl %x\n", vid_dip_ctl);
+       hdmi_write32(IPS_HDMI_VID_DIP_CTL_ADDR, vid_dip_ctl);
+
+       return rc;
+}
+
+/*
+ * Description: disable all infoframes
+ *
+ * @dev:       hdmi_device
+ *
+ * Returns:     OTM_HDMI_ERR_NULL_ARG on NULL parameters
+ *             OTM_HDMI_SUCCESS on success
+ */
+otm_hdmi_ret_t ips_hdmi_disable_all_infoframes(hdmi_device_t *dev)
+{
+       if (!dev)
+               return OTM_HDMI_ERR_NULL_ARG;
+
+       /* Disable Video Related Infoframes */
+       hdmi_write32(IPS_HDMI_VID_DIP_CTL_ADDR, 0x0);
+       /* Disable Audio Related Infoframes */
+       hdmi_write32(IPS_HDMI_AUD_DIP_CTL_ADDR, 0x0);
+
+       /* TODO: Disable other infoframes? */
+
+       return OTM_HDMI_SUCCESS;
+}
+
+/* TODO: revisit: mode into a .h file */
+#define IPS_DOT_MIN                    19750
+#define IPS_DOT_MAX                    120000
+/* Min/Max value based on DPLL parameter interface table
+ * from Penwell Display HAS
+ */
+#define IPS_DPLL_M_MIN_19              105
+#define IPS_DPLL_M_MAX_19              197
+#define IPS_DPLL_P1_MIN_19             2
+#define IPS_DPLL_P1_MAX_19             10
+#define IPS_LIMIT_DPLL_19              0
+#define IPS_VCO_SEL                    (1 << 16)
+
+static const struct ipil_clock_limits_t ipil_clock_limits[] = {
+       {       /* CRYSTAL_19 */
+        .dot = {.min = IPS_DOT_MIN, .max = IPS_DOT_MAX},
+        .m = {.min = IPS_DPLL_M_MIN_19, .max = IPS_DPLL_M_MAX_19},
+        .p1 = {.min = IPS_DPLL_P1_MIN_19, .max = IPS_DPLL_P1_MAX_19},
+        },
+};
+
+/* TODO: revisit: mode into a .h file */
+#define IPS_M_MIN          21
+#define IPS_M_MAX          197
+
+static const u32 ips_m_converts[] = {
+/* M configuration table from 9-bit LFSR table */
+       224, 368, 440, 220, 366, 439, 219, 365, 182, 347, /* 21 - 30 */
+       173, 342, 171, 85, 298, 149, 74, 37, 18, 265,   /* 31 - 40 */
+       388, 194, 353, 432, 216, 108, 310, 155, 333, 166, /* 41 - 50 */
+       83, 41, 276, 138, 325, 162, 337, 168, 340, 170, /* 51 - 60 */
+       341, 426, 469, 234, 373, 442, 221, 110, 311, 411, /* 61 - 70 */
+       461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */
+       106, 53, 282, 397, 354, 227, 113, 56, 284, 142, /* 81 - 90 */
+       71, 35, 273, 136, 324, 418, 465, 488, 500, 506, /* 91 - 100 */
+       253, 126, 63, 287, 399, 455, 483, 241, 376, 444, /* 101 - 110 */
+       478, 495, 503, 251, 381, 446, 479, 239, 375, 443, /* 111 - 120 */
+       477, 238, 119, 315, 157, 78, 295, 147, 329, 420, /* 121 - 130 */
+       210, 105, 308, 154, 77, 38, 275, 137, 68, 290, /* 131 - 140 */
+       145, 328, 164, 82, 297, 404, 458, 485, 498, 249, /* 141 - 150 */
+       380, 190, 351, 431, 471, 235, 117, 314, 413, 206, /* 151 - 160 */
+       103, 51, 25, 12, 262, 387, 193, 96, 48, 280, /* 161 - 170 */
+       396, 198, 99, 305, 152, 76, 294, 403, 457, 228, /* 171 - 180 */
+       114, 313, 156, 334, 423, 467, 489, 244, 378, 445, /*181 - 190 */
+       222, 367, 183, 91, 45, 22, 11, 261, 130, 321, /* 191 - 200 */
+};
+
+/*
+ * Derive the pixel clock for the given refclk and
+ * divisors for 8xx chips.
+ */
+static void __ips_hdmi_derive_dot_clock(int refclk, struct ipil_clock_t *clock)
+{
+       clock->dot = (refclk * clock->m) / clock->p1;
+}
+
+static const struct ipil_clock_limits_t *__ips_hdmi_clk_limits(void)
+{
+       const struct ipil_clock_limits_t *limit = NULL;
+
+       /*
+        * CRYSTAL_19 is enabled for medfield.
+        * Expand this logic for other types.
+        */
+       limit = &ipil_clock_limits[IPS_LIMIT_DPLL_19];
+       return limit;
+}
+
+static bool __ips_hdmi_find_bestPll(int target, int refclk,
+                                       struct ipil_clock_t *best_clock)
+{
+       struct ipil_clock_t clock;
+       const struct ipil_clock_limits_t *limit = __ips_hdmi_clk_limits();
+       int err = target;
+
+       memset(best_clock, 0, sizeof(*best_clock));
+       for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
+               for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
+                    clock.p1++) {
+                       int this_err;
+
+                       __ips_hdmi_derive_dot_clock(refclk, &clock);
+
+                       this_err = abs(clock.dot - target);
+                       if (this_err < err) {
+                               *best_clock = clock;
+                               err = this_err;
+                       }
+               }
+       }
+       return err != target;
+}
+
+/*
+ * Description: gets the best dpll clock value based on
+ *             current timing mode clock.
+ *
+ * @clk:       refresh rate dot clock in kHz of current mode
+ * @pdpll, pfp:        will be set to adjusted dpll values.
+ * @pclock_khz:        tmds clk value for the best pll and is needed for audio.
+ *             This field has to be moved into OTM audio
+ *             interfaces when implemented
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments.
+ */
+otm_hdmi_ret_t ips_hdmi_get_adjusted_clk(unsigned long clk,
+                                       u32 *pdpll, u32 *pfp,
+                                       uint32_t *pclock_khz)
+{
+       int refclk;
+       int clk_n;
+       int clk_p2;
+       int clk_byte = 1;
+       int m_conv = 0;
+       int clk_tmp;
+       u32 dpll, fp;
+       bool ret;
+       struct ipil_clock_t clock;
+
+       /* NULL checks */
+       if (pdpll == NULL || pfp == NULL || pclock_khz == NULL) {
+               pr_debug("\ninvalid argument\n");
+               return OTM_HDMI_ERR_INVAL;
+       }
+
+       /* values corresponds to CRYSTAL_19, as this is enabled on mdfld */
+       refclk = 19200;
+       clk_n = 1;
+       clk_p2 = 10;
+
+       clk_tmp = clk * clk_n * clk_p2 * clk_byte;
+       ret = __ips_hdmi_find_bestPll(clk_tmp, refclk, &clock);
+       /*
+        * TODO: tmds clk value for the best pll found and is needed for audio.
+        * This field has to be moved into OTM audio interfaces
+        * when implemented.
+        */
+       *pclock_khz = clock.dot / (clk_n * clk_p2 * clk_byte);
+       if (ret)
+               m_conv = ips_m_converts[(clock.m - IPS_M_MIN)];
+
+       dpll = 0;
+       dpll |= IPS_VCO_SEL;
+       /* compute bitmask from p1 value */
+       dpll |= (1 << (clock.p1 - 2)) << 17;
+
+       fp = (clk_n / 2) << 16;
+       fp |= m_conv;
+
+       /* update the pointers */
+       *pdpll = dpll;
+       *pfp = fp;
+
+       return OTM_HDMI_SUCCESS;
+}
+
+/*
+ * Description: save HDMI display registers
+ *
+ * @dev:       hdmi_device_t
+ *
+ * Returns:    none
+ */
+void ips_hdmi_save_display_registers(hdmi_device_t *dev)
+{
+       int i;
+       if (NULL == dev)  {
+               pr_debug("\n%s invalid argument\n", __func__);
+               return;
+       }
+
+       dev->reg_state.saveDPLL = hdmi_read32(IPS_DPLL_B);
+       dev->reg_state.saveFPA0 = hdmi_read32(IPS_DPLL_DIV0);
+       dev->reg_state.savePIPEBCONF = hdmi_read32(IPS_PIPEBCONF);
+       dev->reg_state.saveHTOTAL_B = hdmi_read32(IPS_HTOTAL_B);
+       dev->reg_state.saveHBLANK_B = hdmi_read32(IPS_HBLANK_B);
+       dev->reg_state.saveHSYNC_B = hdmi_read32(IPS_HSYNC_B);
+       dev->reg_state.saveVTOTAL_B = hdmi_read32(IPS_VTOTAL_B);
+       dev->reg_state.saveVBLANK_B = hdmi_read32(IPS_VBLANK_B);
+       dev->reg_state.saveVSYNC_B = hdmi_read32(IPS_VSYNC_B);
+       dev->reg_state.savePIPEBSRC = hdmi_read32(IPS_PIPEBSRC);
+       dev->reg_state.saveDSPBSTRIDE = hdmi_read32(IPS_DSPBSTRIDE);
+       dev->reg_state.saveDSPBLINOFF = hdmi_read32(IPS_DSPBLINOFF);
+       dev->reg_state.saveDSPBTILEOFF = hdmi_read32(IPS_DSPBTILEOFF);
+       dev->reg_state.saveDSPBSIZE = hdmi_read32(IPS_DSPBSIZE);
+       dev->reg_state.saveDSPBPOS = hdmi_read32(IPS_DSPBPOS);
+       dev->reg_state.saveDSPBSURF = hdmi_read32(IPS_DSPBSURF);
+       dev->reg_state.saveDSPBCNTR = hdmi_read32(IPS_DSPBCNTR);
+       dev->reg_state.saveDSPBSTATUS = hdmi_read32(IPS_DSPBSTAT);
+
+       /*save palette (gamma) */
+       for (i = 0; i < 256; i++)
+               dev->reg_state.save_palette_b[i] =
+                       hdmi_read32(IPS_PALETTE_B + (i<<2));
+
+       dev->reg_state.savePFIT_CONTROL = hdmi_read32(IPS_PFIT_CONTROL);
+       dev->reg_state.savePFIT_PGM_RATIOS = hdmi_read32(IPS_PFIT_PGM_RATIOS);
+       dev->reg_state.saveHDMIPHYMISCCTL = hdmi_read32(IPS_HDMIPHYMISCCTL);
+       dev->reg_state.saveHDMIB_CONTROL = hdmi_read32(IPS_HDMIB_CONTROL);
+
+       dev->reg_state.valid = true;
+}
+
+/*
+ * Description:        saves HDMI data island packets
+ *
+ * @dev:       hdmi_device_t
+ *
+ * Returns:    none
+ */
+void ips_hdmi_save_data_island(hdmi_device_t *dev)
+{
+       uint32_t index = 0;
+       uint32_t reg_val = 0;
+
+       if (NULL == dev)  {
+               pr_debug("\n%s invalid argument\n", __func__);
+               return;
+       }
+
+       /* Save AVI Infoframe Data */
+       reg_val = hdmi_read32(IPS_HDMI_VID_DIP_CTL_ADDR);
+       if ((reg_val & IPS_HDMI_VID_EN_DIP) &&
+           (reg_val & IPS_HDMI_EN_DIP_TYPE_AVI)) {
+               /* set DIP buffer index to AVI */
+               reg_val &= ~IPS_HDMI_DIP_BUFF_INDX_MASK;
+               reg_val |= IPS_HDMI_DIP_BUFF_INDX_AVI;
+               hdmi_write32(IPS_HDMI_VID_DIP_CTL_ADDR, reg_val);
+               /* set DIP RAM Access Address to 0 */
+               reg_val &= ~IPS_HDMI_DIP_ACCESS_ADDR_MASK;
+               hdmi_write32(IPS_HDMI_VID_DIP_CTL_ADDR, reg_val);
+               reg_val = hdmi_read32(IPS_HDMI_VID_DIP_CTL_ADDR);
+               /* copy transmission frequency */
+               dev->avi.freq =
+                       ((reg_val & IPS_HDMI_DIP_TRANSMISSION_FREQ_MASK) >>
+                               IPS_HDMI_DIP_TX_FREQ_SHIFT);
+               /* copy header */
+               reg_val = hdmi_read32(IPS_HDMI_VIDEO_DIP_DATA_ADDR);
+               dev->avi.pkt.header[0] = reg_val & 0xFF;
+               dev->avi.pkt.header[1] = (reg_val >> 8) & 0xFF;
+               dev->avi.pkt.header[2] = (reg_val >> 16) & 0xFF;
+               /* copy data */
+               for (index = 0; index < (HDMI_DIP_PACKET_DATA_LEN/4); index++) {
+                       dev->avi.pkt.data32[index] =
+                               hdmi_read32(IPS_HDMI_VIDEO_DIP_DATA_ADDR);
+               }
+               /* set data valid */
+               dev->avi.valid = true;
+       } else
+               dev->avi.valid = false;
+}
+
+/*
+ * Description: disable HDMI display
+ *
+ * @dev:       hdmi_device_t
+ *
+ * Returns:    none
+ */
+void ips_disable_hdmi(hdmi_device_t *dev)
+{
+       int count = 0;
+       u32 temp;
+
+       if (NULL == dev)  {
+               pr_debug("\n%s invalid argument\n", __func__);
+               return;
+       }
+
+       /* Disable display plane */
+       temp = hdmi_read32(IPS_DSPBCNTR);
+       if ((temp & IPIL_DSP_PLANE_ENABLE) != 0) {
+               hdmi_write32(IPS_DSPBCNTR, temp & ~IPIL_DSP_PLANE_ENABLE);
+               /* Flush the plane changes */
+               hdmi_write32(IPS_DSPBSURF, hdmi_read32(IPS_DSPBSURF));
+               hdmi_read32(IPS_DSPBSURF);
+       }
+
+       /* Next, disable display pipes */
+       temp = hdmi_read32(IPS_PIPEBCONF);
+       if ((temp & IPIL_PIPEACONF_ENABLE) != 0) {
+               temp &= ~IPIL_PIPEACONF_ENABLE;
+               temp |= IPIL_PIPECONF_PLANE_OFF | IPIL_PIPECONF_CURSOR_OFF;
+               hdmi_write32(IPS_PIPEBCONF, temp);
+               hdmi_read32(IPS_PIPEBCONF);
+
+               /* Wait for for the pipe disable to take effect. */
+               for (count = 0; count < 1000; count++) {
+                       temp = hdmi_read32(IPS_PIPEBCONF);
+                       if (!(temp & IPIL_PIPEACONF_PIPE_STATE))
+                               break;
+
+                       udelay(20);
+               }
+       }
+
+}
+
+/*
+ * Description: restore HDMI display registers and enable display
+ *
+ * @dev:       hdmi_device_t
+ *
+ * Returns:    none
+ */
+void ips_hdmi_restore_and_enable_display(hdmi_device_t *dev)
+{
+       int i;
+       u32 dpll = 0;
+       u32 dpll_val;
+       if (NULL == dev)  {
+               pr_debug("\n%s invalid argument\n", __func__);
+               return;
+       }
+       if (dev->reg_state.valid == false) {
+               pr_debug("\nhdmi no data to restore\n");
+               return;
+       }
+
+       /*make sure VGA plane is off. it initializes to on after reset!*/
+       hdmi_write32(IPIL_VGACNTRL, IPIL_VGA_DISP_DISABLE);
+
+       dpll = hdmi_read32(IPS_DPLL_B);
+       if (!(dpll & IPIL_DPLL_VCO_ENABLE)) {
+               /**
+                * When ungating power of DPLL, needs to wait 0.5us
+                * before enable the VCO
+                */
+               if (dpll & IPIL_DPLL_PWR_GATE_EN) {
+                       dpll &= ~IPIL_DPLL_PWR_GATE_EN;
+                       hdmi_write32(IPS_DPLL_B, dpll);
+                       udelay(1);
+               }
+
+               hdmi_write32(IPS_DPLL_DIV0, dev->reg_state.saveFPA0);
+
+               dpll_val = dev->reg_state.saveDPLL & ~IPIL_DPLL_VCO_ENABLE;
+               hdmi_write32(IPS_DPLL_B, dpll_val);
+               udelay(1);
+
+               dpll_val |= IPIL_DPLL_VCO_ENABLE;
+               hdmi_write32(IPS_DPLL_B, dpll_val);
+               hdmi_read32(IPS_DPLL_B);
+
+       }
+
+       /* Restore mode */
+       hdmi_write32(IPS_HTOTAL_B, dev->reg_state.saveHTOTAL_B);
+       hdmi_write32(IPS_HBLANK_B, dev->reg_state.saveHBLANK_B);
+       hdmi_write32(IPS_HSYNC_B, dev->reg_state.saveHSYNC_B);
+       hdmi_write32(IPS_VTOTAL_B, dev->reg_state.saveVTOTAL_B);
+       hdmi_write32(IPS_VBLANK_B, dev->reg_state.saveVBLANK_B);
+       hdmi_write32(IPS_VSYNC_B, dev->reg_state.saveVSYNC_B);
+       hdmi_write32(IPS_PIPEBSRC, dev->reg_state.savePIPEBSRC);
+       hdmi_write32(IPS_DSPBSTAT, dev->reg_state.saveDSPBSTATUS);
+
+       /*set up the plane*/
+       hdmi_write32(IPS_DSPBSTRIDE, dev->reg_state.saveDSPBSTRIDE);
+       hdmi_write32(IPS_DSPBLINOFF, dev->reg_state.saveDSPBLINOFF);
+       hdmi_write32(IPS_DSPBTILEOFF, dev->reg_state.saveDSPBTILEOFF);
+       hdmi_write32(IPS_DSPBSIZE, dev->reg_state.saveDSPBSIZE);
+       hdmi_write32(IPS_DSPBPOS, dev->reg_state.saveDSPBPOS);
+       hdmi_write32(IPS_DSPBSURF, dev->reg_state.saveDSPBSURF);
+
+       hdmi_write32(IPS_PFIT_CONTROL, dev->reg_state.savePFIT_CONTROL);
+       hdmi_write32(IPS_PFIT_PGM_RATIOS, dev->reg_state.savePFIT_PGM_RATIOS);
+       hdmi_write32(IPS_HDMIPHYMISCCTL, dev->reg_state.saveHDMIPHYMISCCTL);
+       hdmi_write32(IPS_HDMIB_CONTROL, dev->reg_state.saveHDMIB_CONTROL);
+
+       /*enable the plane*/
+       hdmi_write32(IPS_DSPBCNTR, dev->reg_state.saveDSPBCNTR);
+
+       if (in_atomic() || in_interrupt())
+               udelay(20000);
+       else
+               msleep_interruptible(20);
+
+       /*enable the pipe */
+       hdmi_write32(IPS_PIPEBCONF, dev->reg_state.savePIPEBCONF);
+
+       /* restore palette (gamma) */
+       for (i = 0; i < 256; i++)
+               hdmi_write32(IPS_PALETTE_B + (i<<2),
+                               dev->reg_state.save_palette_b[i]);
+
+       dev->reg_state.valid = false;
+}
+
+/*
+ * Description: restore HDMI data island packets
+ *
+ * @dev:       hdmi_device_t
+ *
+ * Returns:    none
+ */
+void ips_hdmi_restore_data_island(hdmi_device_t *dev)
+{
+       if (NULL == dev)  {
+               pr_debug("\n%s invalid argument\n", __func__);
+               return;
+       }
+
+       /* restore AVI infoframe */
+       if (dev->avi.valid) {
+               if (ips_hdmi_enable_vid_infoframe(dev, HDMI_PACKET_AVI,
+                               &dev->avi.pkt, dev->avi.freq) !=
+                               OTM_HDMI_SUCCESS)
+                       pr_debug("\nfailed to program avi infoframe\n");
+               dev->avi.valid = false;
+       }
+}
+
+/*
+ * Description: destroys any saved HDMI data
+ *
+ * @dev:        hdmi_device_t
+ *
+ * Returns: none
+ */
+void ips_hdmi_destroy_saved_data(hdmi_device_t *dev)
+{
+       if (NULL != dev) {
+               dev->reg_state.valid = false;
+               dev->avi.valid = false;
+       }
+}
diff --git a/drivers/staging/mrst/drv/otm_hdmi/ipil/specific/mfld/mfld_hdcp_reg.h b/drivers/staging/mrst/drv/otm_hdmi/ipil/specific/mfld/mfld_hdcp_reg.h
new file mode 100644 (file)
index 0000000..a2bd817
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef MFLD_HDCP_REG_H
+#define MFLD_HDCP_REG_H
+
+
+/* Register Definitions */
+#define MDFLD_HDMIB_CNTRL_REG          0x61140
+#define MDFLD_HDMIB_HDCP_PORT_SEL      (0x1 << 5)
+
+/* HDCP Config & Status */
+#define MDFLD_HDCP_CONFIG_REG          0x61400
+#define MDFLD_HDCP_STATUS_REG          0x61448
+/* AN & AKSV */
+#define MDFLD_HDCP_INIT_REG            0x61404
+#define MDFLD_HDCP_AN_LOW_REG          0x61410
+#define MDFLD_HDCP_AN_HI_REG           0x61414
+#define MDFLD_HDCP_AKSV_HI_REG         0x61450
+#define MDFLD_HDCP_AKSV_LOW_REG                0x61454
+/* BKSV */
+#define MDFLD_HDCP_BKSV_LOW_REG                0x61408
+#define MDFLD_HDCP_BKSV_HI_REG         0x6140C
+/* Rx-Ri */
+#define MDFLD_HDCP_RECEIVER_RI_REG     0x61418
+/* Repeater Control & Status */
+#define MDFLD_HDCP_REP_REG             0x61444
+/* Repeater SHA */
+#define MDFLD_HDCP_VPRIME_H0           0x6142C
+#define MDFLD_HDCP_VPRIME_H1           0x61430
+#define MDFLD_HDCP_VPRIME_H2           0x61434
+#define MDFLD_HDCP_VPRIME_H3           0x61438
+#define MDFLD_HDCP_VPRIME_H4           0x6143C
+#define MDFLD_HDCP_SHA1_IN             0x61440
+/* Akey */
+#define MDFLD_HDCP_AKEY_LO_REG         0x6141C
+#define MDFLD_HDCP_AKEY_MED_REG                0x61420
+#define MDFLD_HDCP_AKEY_HI_REG         0x61424
+
+
+struct double_word_t {
+       union {
+               uint64_t value;
+               struct {
+                       uint32_t low;
+                       uint32_t high;
+               };
+               struct {
+                       uint8_t byte[8];
+               };
+       };
+};
+
+
+enum ips_hdcp_config_enum {
+       HDCP_Off = 0,
+       HDCP_CAPTURE_AN = 1,
+       HDCP_DECRYPT_KEYS = 2,
+       HDCP_AUTHENTICATE_AND_ENCRYPT = 3,
+       HDCP_UNIQUE_MCH_ID = 5,
+       HDCP_ENCRYPT_KEYS = 6,
+       HDCP_CYPHER_CHECK_MODE = 7
+};
+
+struct ips_hdcp_config_reg_t {
+               union {
+               uint32_t value;
+               struct {
+                       uint32_t hdcp_config:3;
+                       uint32_t reserved:29;
+               };
+       };
+};
+
+struct ips_hdcp_status_reg_t {
+       union {
+               uint32_t value;
+               struct {
+                       uint32_t ainfo:8;
+                       uint32_t frame_count:8;
+                       uint32_t hdcp_on:1;
+                       uint32_t an_ready:1;
+                       uint32_t ri_ready:1;
+                       uint32_t ri_match:1;
+                       uint32_t encrypting:1;
+                       uint32_t ready_for_encr:1;
+                       uint32_t umch_id_ready:1;
+                       uint32_t mac_status:1;
+                       uint32_t fus_complete:1;
+                       uint32_t fus_success:1;
+                       uint32_t reserved:6;
+               };
+       };
+};
+
+/* Repeater Control register */
+enum ips_hdcp_repeater_status_enum {
+       HDCP_REPEATER_STATUS_IDLE = 0,
+       HDCP_REPEATER_STATUS_BUSY = 1,
+       HDCP_REPEATER_STATUS_RDY_NEXT_DATA = 2,
+       HDCP_REPEATER_STATUS_COMPLETE_NO_MATCH = 4,
+       HDCP_REPEATER_STATUS_COMPLETE_MATCH = 12
+};
+
+enum ips_hdcp_repeater_ctrl_enum {
+       HDCP_REPEATER_CTRL_IDLE = 0,
+       HDCP_REPEATER_32BIT_TEXT_IP = 1,
+       HDCP_REPEATER_COMPLETE_SHA1 = 2,
+       HDCP_REPEATER_24BIT_TEXT_8BIT_MO_IP = 4,
+       HDCP_REPEATER_16BIT_TEXT_16BIT_MO_IP = 5,
+       HDCP_REPEATER_8BIT_TEXT_24BIT_MO_IP = 6,
+       HDCP_REPEATER_32BIT_MO_IP = 7
+};
+
+struct ips_hdcp_repeater_reg_t {
+       union {
+               uint32_t value;
+               struct {
+                       uint32_t present:1;
+                       uint32_t control:3;
+                       uint32_t reserved1:12;
+                       const uint32_t status:4;
+                       uint32_t reserved2:12;
+               };
+       };
+};
+
+#endif /* MFLD_HDCP_REG_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/ipil/specific/mfld/mfld_hdmi_reg.h b/drivers/staging/mrst/drv/otm_hdmi/ipil/specific/mfld/mfld_hdmi_reg.h
new file mode 100644 (file)
index 0000000..ea720d1
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef __MFLD_HDMI_REG_H
+#define __MFLD_HDMI_REG_H
+
+#define IPS_HDMI_OCP_STATUS                    (1 << 2)
+#define IPS_HDMI_HPD_STATUS_BIT                        (1 << 3)
+
+#define IPS_MSIC_VCC330CNT                     0xd3
+#define IPS_VCC330_OFF                         0x24
+#define IPS_VCC330_ON                          0x37
+#define IPS_MSIC_VHDMICNT                      0xde
+#define IPS_VHDMI_OFF                          0x24
+#define IPS_VHDMI_ON                           0xa4
+#define IPS_VHDMI_DB_30MS                      0x60
+
+/* Video Data Island Packet Control */
+#define IPS_HDMI_VID_DIP_CTL_ADDR              (0x61170)
+
+#define IPS_HDMI_VID_EN_DIP                    ((1) << 31)
+#define IPS_HDMI_VID_PORT_SELECT_MASK          ((0x3) << 29)
+#define IPS_HDMI_VID_PORT_B_SELECT             ((1) << 29)
+
+/* Video DIP Type Values Bits 24:21 */
+#define IPS_HDMI_EN_DIP_TYPE_MASK              ((0xF) << 21)
+#define IPS_HDMI_EN_DIP_TYPE_AVI               ((1) << 21)
+#define IPS_HDMI_EN_DIP_TYPE_VS                        ((1) << 22)
+#define IPS_HDMI_EN_DIP_TYPE_SPD               ((1) << 24)
+
+/* Video DIP Type Buffer Index Bits 20:19 */
+#define IPS_HDMI_DIP_BUFF_INDX_MASK            ((0x3) << 19)
+#define IPS_HDMI_DIP_BUFF_INDX_AVI             ((0x0) << 19)
+#define IPS_HDMI_DIP_BUFF_INDX_VS              ((0x1) << 19)
+#define IPS_HDMI_DIP_BUFF_INDX_SPD             ((0x3) << 19)
+
+/* Video Dip Transmission Frequency 17:16 */
+#define IPS_HDMI_DIP_TX_FREQ_SHIFT             (16)
+#define IPS_HDMI_DIP_TRANSMISSION_FREQ_MASK    ((0x3) << 16)
+
+/* Video Dip Access Address 3:0 */
+#define IPS_HDMI_DIP_ACCESS_ADDR_MASK          (0xF)
+
+/* Video Dip Data Register */
+#define IPS_HDMI_VIDEO_DIP_DATA_ADDR           (0x61178)
+
+/* Audio Data Island Packet Control */
+#define IPS_HDMI_AUD_DIP_CTL_ADDR              (0x69060)
+
+#endif /* MFLD_HDMI_REG_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/ipil/specific/mfld/mfld_utils.h b/drivers/staging/mrst/drv/otm_hdmi/ipil/specific/mfld/mfld_utils.h
new file mode 100644 (file)
index 0000000..0ca05d7
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef IPS_API_H
+#define IPS_API_H
+
+extern uint32_t hdmi_read32(uint32_t reg);
+extern void hdmi_write32(uint32_t reg, uint32_t val);
+extern int intel_scu_ipc_iowrite8(u16 addr, u8 data);
+
+#endif /* IPS_API_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/os/android/android_hdmi.c b/drivers/staging/mrst/drv/otm_hdmi/os/android/android_hdmi.c
new file mode 100644 (file)
index 0000000..60e3acd
--- /dev/null
@@ -0,0 +1,1538 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+/* Definition for debug print format */
+#define pr_fmt(fmt)    "[otm_hdmi]: " fmt
+
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/switch.h>
+#include "psb_intel_drv.h"
+#include "psb_intel_reg.h"
+#include "psb_drv.h"
+
+#include "otm_hdmi_types.h"
+#include "otm_hdmi.h"
+#include "android_hdmi.h"
+#ifdef OTM_HDMI_HDCP_ENABLE
+#include "hdcp_api.h"
+#endif
+
+/* TODO: need to remove this, once I2C issue is worked out. */
+#include <asm/intel_scu_ipc.h>
+#include "psb_intel_hdmi.h"
+#include "psb_powermgmt.h"
+
+/* TODO: metadata should be populated using table from mode_info.c */
+static const struct {
+       int width, height, htotal, vtotal, dclk, vrefr, vic;
+} vic_formats[11] = {
+       {  640,  480,  800,  525,  25200, 60,  1 }, /* 640x480p60 4:3 */
+       {  720,  480,  858,  525,  27027, 60,  2 }, /* 720x480p60 4:3 */
+       {  720,  480,  858,  525,  27027, 60,  3 }, /* 720x480p60 16:9 */
+       { 1280,  720, 1650,  750,  74250, 60,  4 }, /* 1280x720p60 16:9 */
+       { 1920, 1080, 2200, 1125, 148500, 60, 16 }, /* 1920x1080p60 16:9 */
+       {  720,  576,  864,  625,  27000, 50, 17 }, /* 720x576p50 4:3 */
+       {  720,  576,  864,  625,  27000, 50, 18 }, /* 720x576p50 16:9 */
+       { 1280,  720, 1980,  750,  74250, 50, 19 }, /* 1280x720p50 16:9 */
+       { 1920, 1080, 2750, 1125,  74250, 24, 32 }, /* 1920x1080p24 16:9 */
+       { 1920, 1080, 2640, 1125,  74250, 25, 33 }, /* 1920x1080p25 16:9 */
+       { 1920, 1080, 2200, 1125,  74250, 30, 34 }, /* 1920x1080p30 16:9 */
+};
+
+/* Function declarations for interrupt routines */
+/*
+ * android_hdmi_irq_callback:
+ * Description:IRQ interrupt bottomhalf handler callback. This callback
+ *             will be called for hdmi plug/unplug interrupts.
+ * Parameters : irq: IRQ number
+ *             data: hdmi_priv data
+ * Return     : IRQ_HANDLED
+ */
+static irqreturn_t android_hdmi_irq_callback(int irq, void *data);
+static irqreturn_t __hdmi_irq_handler_bottomhalf(void *data);
+
+static int calculate_refresh_rate(struct drm_display_mode *mode);
+
+/*
+ * TODO: Remove this structure and counter afer EDID Parse
+ *      for established modes is implemented
+ */
+#define DEBUG_MODES 100
+struct debug_modes__t {
+       int clk;
+       int frq;
+       char name[DRM_DISPLAY_MODE_LEN + 1];
+} arr_modes[DEBUG_MODES];
+
+u32 debug_modes_count;
+
+#define SWITCH_DEV_HDMI_NAME "hdmi"
+#define SWITCH_DEV_DVI_NAME "dvi"
+
+#define WPT_IOBAR_OFFSET_BASE     0x1F0000
+#define WPT_IOBAR_INDEX_REGISTER       0x2110
+#define WPT_IOBAR_DATA_REGISTER         0x2114
+
+/* Default HDMI Edid - 640x480p 720x480p 1280x720p */
+static unsigned char default_edid[] = {
+       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
+       0x25, 0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x14, 0x01, 0x03, 0x80, 0x00, 0x00, 0xFF,
+       0x2A, 0xBA, 0x45, 0xA1, 0x59, 0x55, 0x9D, 0x28,
+       0x0D, 0x50, 0x54, 0x20, 0x00, 0x00, 0x01, 0x01,
+       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1D,
+       0x00, 0x72, 0x51, 0xD0, 0x1E, 0x20, 0x6E, 0x28,
+       0x55, 0x00, 0xC4, 0x8E, 0x21, 0x00, 0x00, 0x1E,
+       0x8F, 0x0A, 0xD0, 0x8A, 0x20, 0xE0, 0x2D, 0x10,
+       0x10, 0x3E, 0x96, 0x00, 0xC4, 0x8E, 0x21, 0x00,
+       0x00, 0x18, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x49,
+       0x4E, 0x54, 0x45, 0x4C, 0x2D, 0x54, 0x56, 0x0A,
+       0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xFD,
+       0x0C, 0x37, 0x3D, 0x1F, 0x31, 0x0F, 0x00, 0x0A,
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0xCE,
+       0x02, 0x03, 0x13, 0x41, 0x42, 0x04, 0x02, 0x23,
+       0x09, 0x07, 0x07, 0x67, 0x03, 0x0C, 0x00, 0x10,
+       0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B
+};
+
+/*store the state whether the edid is ready
+ *in HPD (1) or not (0)*/
+static int edid_ready_in_hpd = 0;
+
+static irqreturn_t __hdmi_irq_handler_bottomhalf(void *data)
+{
+       struct android_hdmi_priv *hdmi_priv = data;
+       bool hpd = otm_hdmi_power_rails_on();
+
+       if ((true == hpd) && (hdmi_priv != NULL)) {
+               /* Get monitor type. This is required to appropriately
+                * issue switch class event to the user space depending
+                * on the monitor type - HDMI or DVI.
+                */
+               struct drm_mode_config *mode_config = NULL;
+               struct edid *edid = NULL;
+               struct drm_connector *connector = NULL;
+               struct i2c_adapter *adapter = NULL;
+               u8 hdmi_status = 0;
+#ifndef OTM_HDMI_FIXME
+               /*OTM_HDMI_FIXME: this should be from get attribute interface*/
+               int adapter_num = 3;
+#endif
+
+               if (!hdmi_priv->dev)
+                       return IRQ_HANDLED;
+
+               /* Check HDMI status, read EDID only if connected */
+               intel_scu_ipc_ioread8(MSIC_HDMI_STATUS, &hdmi_status);
+#ifdef OTM_HDMI_HDCP_ENABLE
+               otm_hdmi_hdcp_set_hpd_state(hdmi_priv->context,
+                               (hdmi_status & HPD_SIGNAL_STATUS));
+#endif
+               if (!(hdmi_status & HPD_SIGNAL_STATUS))
+                       goto exit;
+
+               adapter = i2c_get_adapter(adapter_num);
+               if (!adapter) {
+                       pr_err("Unable to get i2c adapter for HDMI");
+                       goto exit;
+               }
+
+               mode_config = &hdmi_priv->dev->mode_config;
+               list_for_each_entry(connector,
+                                       &mode_config->connector_list,
+                                       head) {
+                       if (!connector)
+                               continue;
+                       if (DRM_MODE_CONNECTOR_DVID ==
+                               connector->connector_type) {
+                               edid = (struct edid *)
+                                       drm_get_edid(connector, adapter);
+                               if (edid) {
+                                       if (drm_detect_hdmi_monitor(edid))
+                                               /* MONITOR_TYPE_HDMI */
+                                               hdmi_priv->monitor_type = 1;
+                                       else
+                                               /* MONITOR_TYPE_DVI */
+                                               hdmi_priv->monitor_type = 2;
+                                       /* Store raw edid in HDMI context */
+                                       otm_hdmi_set_raw_edid(
+                                               hdmi_priv->context,
+                                               (char *)edid);
+                                       /* Raw edid is ready in HDMI context */
+                                       edid_ready_in_hpd = 1;
+                                       kfree(edid);
+                               } else {
+                                       pr_err("Edid Read failed");
+                                       /* Retry in next get modes */
+                                       edid_ready_in_hpd = 0;
+                               }
+                               break;
+                       }
+               }
+exit:
+               /* Notify user space */
+               drm_helper_hpd_irq_event(hdmi_priv->dev);
+       }
+
+       return IRQ_HANDLED;
+}
+
+#ifdef OTM_HDMI_FIXME
+gdl_ret_t android_hdmi_audio_control(void *context, bool flag)
+{
+       hdmi_context_t *ctx = (hdmi_context_t *)context;
+       hdmi_device_t *dev = &ctx->dev;
+       gdl_ret_t rc = GDL_SUCCESS;
+
+       if (flag) {
+               /* Enable audio */
+               IOW(HDMI_UNIT_CONTROL, 0x67);
+               IOR(HDMI_UNIT_CONTROL);
+
+               IOW(0x51a8, 0x10);
+               IOR(0x51a8);
+
+               IOW(HDMI_AUDIO_CONTROL, 0x1);
+               IOR(HDMI_AUDIO_CONTROL);
+       } else {
+               /* Disable audio */
+               IOW(0x51a8, 0x0);
+               IOR(0x51a8);
+
+               IOW(HDMI_AUDIO_CONTROL, 0x0);
+               IOR(HDMI_AUDIO_CONTROL);
+
+               IOW(HDMI_UNIT_CONTROL, 0x47);
+               IOR(HDMI_UNIT_CONTROL);
+       }
+
+       return rc;
+}
+#endif
+
+static int hdmi_ddc_read_write(bool read,
+                       uint8_t i2c_addr,
+                       uint8_t offset,
+                       uint8_t *buffer,
+                       int size)
+{
+#ifndef OTM_HDMI_FIXME
+       /* OTM_HDMI_FIXME: this should be from get attribute interface */
+       int adapter_num = 3;
+#endif
+       struct i2c_adapter *adapter = i2c_get_adapter(adapter_num);
+       struct i2c_msg msgs[] = {
+               {
+                       .addr   = i2c_addr,
+                       .flags  = 0,
+                       .len    = 1,
+                       .buf    = &offset,
+               }, {
+                       .addr   = i2c_addr,
+                       .flags  = ((read) ? I2C_M_RD : 0),
+                       .len    = size,
+                       .buf    = buffer,
+               }
+       };
+
+       if (adapter != NULL && i2c_transfer(adapter, msgs, 2) == 2)
+               return 1;
+
+       return 0;
+}
+
+#define android_hdmi_connector_funcs mdfld_hdmi_connector_funcs
+#define android_hdmi_connector_helper_funcs mdfld_hdmi_connector_helper_funcs
+#define android_hdmi_enc_helper_funcs mdfld_hdmi_helper_funcs
+#define android_hdmi_enc_funcs psb_intel_lvds_enc_funcs
+
+void android_hdmi_driver_init(struct drm_device *dev,
+                                   void *mode_dev)
+{
+       struct drm_psb_private *dev_priv = dev->dev_private;
+       struct android_hdmi_priv *hdmi_priv = dev_priv->hdmi_priv;
+       struct psb_intel_output *psb_intel_output;
+       struct drm_connector *connector;
+       struct drm_encoder *encoder;
+
+       pr_debug("%s E", __func__);
+
+       psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
+       if (!psb_intel_output)
+               return;
+
+       psb_intel_output->mode_dev = mode_dev;
+       connector = &psb_intel_output->base;
+       encoder = &psb_intel_output->enc;
+       drm_connector_init(dev, &psb_intel_output->base,
+                          &android_hdmi_connector_funcs,
+                          DRM_MODE_CONNECTOR_DVID);
+
+       drm_encoder_init(dev, &psb_intel_output->enc, &android_hdmi_enc_funcs,
+                        DRM_MODE_ENCODER_TMDS);
+
+       drm_mode_connector_attach_encoder(&psb_intel_output->base,
+                                         &psb_intel_output->enc);
+       psb_intel_output->type = INTEL_OUTPUT_HDMI;
+
+       psb_intel_output->dev_priv = hdmi_priv;
+
+       drm_encoder_helper_add(encoder, &android_hdmi_enc_helper_funcs);
+       drm_connector_helper_add(connector,
+                                &android_hdmi_connector_helper_funcs);
+
+       drm_connector_attach_property(connector,
+                                       dev->mode_config.scaling_mode_property,
+                                       DRM_MODE_SCALE_ASPECT);
+
+       connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+       connector->interlace_allowed = false;
+       connector->doublescan_allowed = false;
+
+       /* Enable polling */
+       connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+       /* hard-coded the HDMI_I2C_ADAPTER_ID to be 3, Should get from GCT*/
+       /* TODO: remove this once all code moved into OTM */
+       psb_intel_output->hdmi_i2c_adapter = i2c_get_adapter(3);
+
+       if (psb_intel_output->hdmi_i2c_adapter)
+               /* HACKS_JLIU7 */
+               pr_debug("Enter mdfld_hdmi_init, i2c_adapter is availabe.\n");
+       else
+               printk(KERN_ALERT "No ddc adapter available!\n");
+       hdmi_priv->hdmi_i2c_adapter = psb_intel_output->hdmi_i2c_adapter;
+#ifdef OTM_HDMI_HDCP_ENABLE
+       otm_hdmi_hdcp_init(hdmi_priv->context, &hdmi_ddc_read_write);
+#endif
+       mdfld_hdmi_audio_init(hdmi_priv);
+       mdfld_msic_init(hdmi_priv);
+
+       pr_debug("%s X", __func__);
+}
+
+void android_hdmi_enable_hotplug(struct drm_device *dev)
+{
+       struct drm_psb_private *dev_priv = dev->dev_private;
+       struct android_hdmi_priv *hdmi_priv = dev_priv->hdmi_priv;
+
+       /* Drm is ready for incoming HPD now */
+       if (otm_hdmi_setup_irq(hdmi_priv->context, dev->pdev,
+                               &android_hdmi_irq_callback,
+                               (void *)hdmi_priv)) {
+               pr_err("failed to initialize hdmi HPD IRQ\n");
+               return;
+       }
+}
+
+/*
+ * android_hdmi_irq_callback:
+ * Description: IRQ interrupt bottomhalf handler callback. This callback
+ *             will be called for hdmi plug/unplug interrupts.
+ * Parameters : irq: IRQ number
+ *             data: hdmi_priv data
+ * Return     : IRQ_HANDLED
+ */
+static irqreturn_t android_hdmi_irq_callback(int irq, void *data)
+{
+       pr_debug("%s: IRQ Interrupt callback", __func__);
+
+       return __hdmi_irq_handler_bottomhalf(data);
+}
+
+void android_hdmi_driver_setup(struct drm_device *dev)
+{
+       struct drm_psb_private *dev_priv = dev->dev_private;
+       struct android_hdmi_priv *hdmi_priv;
+       int ret;
+
+       pr_debug("%s E", __func__);
+
+       /* HDMI private data */
+       hdmi_priv = kzalloc(sizeof(struct android_hdmi_priv), GFP_KERNEL);
+       if (!hdmi_priv) {
+               pr_err("failed to allocate memory");
+               goto out;
+       }
+
+       pr_debug("%s: Initialize the HDMI device", __func__);
+       /* Initialize the HDMI context */
+       if (otm_hdmi_device_init(&(hdmi_priv->context), dev->pdev)) {
+               pr_err("failed to initialize hdmi device\n");
+               goto free;
+       }
+
+       hdmi_priv->dev = dev;
+
+       /* TODO: No need to expose these values to outside.
+        * keeping for now as oktl psb files are referring these.
+        * has to be removed when cleaning up the oktl psb files.
+        * medfield psb files don't need this, hence disabling
+        */
+       /* hdmi_priv->regs = ctx->io_address; */
+
+       /*FIXME: May need to get this somewhere,
+        * but CG code seems hard coded it
+        */
+       hdmi_priv->hdmib_reg = HDMIB_CONTROL;
+       hdmi_priv->has_hdmi_sink = false;
+       /* TODO: get this from get/set attribute table.
+        */
+       hdmi_priv->monitor_type = 1;/* MONITOR_TYPE_HDMI */
+       /* TODO: set this to false for oaktrail */
+       /* TODO: get this from get/set attribute table.
+        */
+       hdmi_priv->is_hdcp_supported = true;
+
+       dev_priv->hdmi_priv = (void *)hdmi_priv;
+       dev_priv->hdmi_present = 1;
+
+       pr_debug("%s: Register switch class devices", __func__);
+       /* Register as a switch class device */
+       g_switch_hdmi_dev.name = SWITCH_DEV_HDMI_NAME;
+       ret = switch_dev_register(&g_switch_hdmi_dev);
+       if (ret) {
+               pr_debug("Failed to register switch class device %s (%d)",
+                               SWITCH_DEV_HDMI_NAME, ret);
+               goto free;
+       }
+
+       g_switch_dvi_dev.name = SWITCH_DEV_DVI_NAME;
+       ret = switch_dev_register(&g_switch_dvi_dev);
+       if (ret) {
+               pr_debug("Failed to register switch class device %s (%d)",
+                               SWITCH_DEV_DVI_NAME, ret);
+               goto free;
+       }
+
+#ifdef OTM_HDMI_FIXME
+       android_hdmi_audio_control(hdmi_priv->context, false);
+        /* request io port region for audio configuration */
+       res = request_region(WPT_IOBAR_INDEX_REGISTER,
+                       WPT_IOBAR_DATA_REGISTER - WPT_IOBAR_INDEX_REGISTER + 1,
+                       "OKTLHDMI");
+       if (res == NULL) {
+               pr_err("Failed to allocate io port region\n");
+               goto free;
+       }
+#endif
+       pr_debug("%s X", __func__);
+       return;
+free:
+       kfree(hdmi_priv);
+out:
+       dev_priv->hdmi_present = 0;
+       return;
+}
+
+/* structure for hdmi cmdline module
+ * don't upstream the code
+ */
+typedef struct {
+       int hdisplay, vdisplay;
+       int refresh;
+       int refresh_specified;
+       int vic;
+       int vic_specified;
+       int specified; /* 1: cmdline_mode is set */
+} otm_cmdline_mode;
+
+static otm_cmdline_mode cmdline_mode = { 0, 0, 0, 0, 0, 0, 0 };
+
+int otm_cmdline_parse_option(char *cmdoption)
+{
+       int ret = 0;
+       int namelen = 0;
+       int i;
+       int v_spec = 0;
+       char *name;
+       if (NULL == cmdoption)
+               return -1;
+
+       cmdline_mode.specified = 0;
+       cmdline_mode.refresh_specified = 0;
+       cmdline_mode.vic_specified = 0;
+
+       name = cmdoption;
+       namelen = strlen(name);
+       for (i = namelen-1; i >= 0; i--) {
+               switch (name[i]) {
+               case '@':
+                       namelen = i;
+                       cmdline_mode.refresh =
+                               simple_strtol(&name[i+1], NULL, 10);
+                       cmdline_mode.refresh_specified = 1;
+                       break;
+               case 'x':
+               case 'X':
+                       cmdline_mode.vdisplay =
+                               simple_strtol(&name[i+1], NULL, 10);
+                       v_spec = 1;
+                       break;
+               case '0' ... '9':
+                       break;
+               default:
+                       /* invalid input */
+                       return -2;
+               }
+       }
+
+       if ((i < 0) && (1 == v_spec))
+               cmdline_mode.hdisplay = simple_strtol(name, NULL, 10);
+
+       cmdline_mode.specified = 1;
+       return ret;
+}
+EXPORT_SYMBOL_GPL(otm_cmdline_parse_option);
+
+int otm_cmdline_set_vic_option(int vic)
+{
+       int i = 0;
+
+       cmdline_mode.specified = 0;
+       cmdline_mode.refresh_specified = 0;
+       cmdline_mode.vic_specified = 0;
+
+       for (i = 0; i < ARRAY_SIZE(vic_formats); i++) {
+               if (vic == vic_formats[i].vic) {
+                       cmdline_mode.refresh = vic_formats[i].vrefr;
+                       cmdline_mode.hdisplay = vic_formats[i].width;
+                       cmdline_mode.vdisplay = vic_formats[i].height;
+                       cmdline_mode.vic = vic;
+                       cmdline_mode.specified = 1;
+                       cmdline_mode.refresh_specified = 1;
+                       cmdline_mode.vic_specified = 1;
+                       return 0;
+               }
+       }
+
+       printk(KERN_INFO "HDMI cmdline: Unsupported VIC(%d) specified\n", vic);
+       return -1;
+}
+EXPORT_SYMBOL_GPL(otm_cmdline_set_vic_option);
+
+void otm_print_cmdline_option()
+{
+       if (1 == cmdline_mode.specified) {
+               if (1 == cmdline_mode.vic_specified)
+                       printk(KERN_INFO "HDMI cmdline option: %dx%d@%d (%d)\n",
+                               cmdline_mode.hdisplay,
+                               cmdline_mode.vdisplay,
+                               cmdline_mode.refresh,
+                               cmdline_mode.vic);
+               else if (1 == cmdline_mode.refresh_specified)
+                       printk(KERN_INFO "HDMI cmdline option: %dx%d@%d\n",
+                               cmdline_mode.hdisplay,
+                               cmdline_mode.vdisplay,
+                               cmdline_mode.refresh);
+               else
+                       printk(KERN_INFO "HDMI cmdline option: %dx%d\n",
+                               cmdline_mode.hdisplay, cmdline_mode.vdisplay);
+       } else
+               printk(KERN_INFO "HDMI cmdline option is not set\n");
+}
+EXPORT_SYMBOL_GPL(otm_print_cmdline_option);
+
+/*
+ * DRM connector helper routine.
+ */
+int android_hdmi_mode_valid(struct drm_connector *connector,
+                               struct drm_display_mode *mode)
+{
+       unsigned int pc_min, pc_max;
+
+       pr_debug("display info. hdisplay = %d, vdisplay = %d, clock = %d.\n",
+                       mode->hdisplay, mode->vdisplay, mode->clock);
+
+       /* Restricting modes within the supported pixel clock */
+       if (OTM_HDMI_SUCCESS == otm_hdmi_get_pixel_clock_range(
+                                       &pc_min, &pc_max)) {
+               if (mode->clock < pc_min) {
+                       pr_debug("pruned mode %dx%d@%d.\n",
+                               mode->hdisplay,
+                               mode->vdisplay,
+                               mode->clock);
+                       return MODE_CLOCK_LOW;
+               }
+               if (mode->clock > pc_max) {
+                       pr_debug("pruned mode %dx%d@%d.\n",
+                               mode->hdisplay,
+                               mode->vdisplay,
+                               mode->clock);
+                       return MODE_CLOCK_HIGH;
+               }
+       }
+
+#ifdef MFLD_HDMI_PR3
+       /* if cmdline_mode is set, prune all other modes.*/
+       if (1 == cmdline_mode.specified) {
+               if ((cmdline_mode.hdisplay != mode->hdisplay) ||
+                       (cmdline_mode.vdisplay != mode->vdisplay) ||
+                       ((1 == cmdline_mode.refresh_specified) &&
+                       (cmdline_mode.refresh !=
+                       calculate_refresh_rate(mode)))) {
+                       return MODE_BAD;
+               }
+       }
+#endif
+
+       if (mode->type == DRM_MODE_TYPE_USERDEF)
+               return MODE_OK;
+
+       if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+               return MODE_NO_DBLESCAN;
+
+       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+               return MODE_NO_INTERLACE;
+
+       return MODE_OK;
+}
+
+static struct drm_display_mode
+*android_hdmi_get_drm_mode_from_pdt(otm_hdmi_timing_t *timings,
+                                   struct drm_device *dev)
+{
+       struct drm_display_mode *mode;
+       int i;
+       static const struct {
+       int w, h;
+       } cea_interlaced[7] = {
+               { 1920, 1080 },
+               {  720,  480 },
+               { 1440,  480 },
+               { 2880,  480 },
+               {  720,  576 },
+               { 1440,  576 },
+               { 2880,  576 },
+       };
+
+       if (timings == NULL || dev == NULL)
+               return NULL;
+
+       mode = drm_mode_create(dev);
+       if (mode == NULL)
+               return NULL;
+
+       mode->type = DRM_MODE_TYPE_DRIVER;
+       mode->clock = timings->dclk;
+
+       mode->hdisplay = timings->width;
+       mode->hsync_start = timings->hsync_start;
+       mode->hsync_end = timings->hsync_end;
+       mode->htotal = timings->htotal;
+
+       mode->vdisplay = timings->height;
+       mode->vsync_start = timings->vsync_start;
+       mode->vsync_end = timings->vsync_end;
+       mode->vtotal = timings->vtotal;
+
+       if (timings->mode_info_flags & PD_SCAN_INTERLACE) {
+
+               mode->flags |= DRM_MODE_FLAG_INTERLACE;
+
+               for (i = 0; i < ARRAY_SIZE(cea_interlaced); i++) {
+                       if ((mode->hdisplay == cea_interlaced[i].w) &&
+                           (mode->vdisplay == cea_interlaced[i].h / 2)) {
+                               mode->vdisplay *= 2;
+                               mode->vsync_start *= 2;
+                               mode->vsync_end *= 2;
+                               mode->vtotal *= 2;
+                               mode->vtotal |= 1;
+                       }
+               }
+       }
+
+       drm_mode_set_name(mode);
+
+       mode->flags |= (timings->mode_info_flags & PD_HSYNC_HIGH) ?
+               DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC;
+       mode->flags |= (timings->mode_info_flags & PD_VSYNC_HIGH) ?
+               DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC;
+
+       return mode;
+}
+
+static int android_hdmi_add_cea_edid_modes(struct drm_connector *connector,
+                                          struct edid *edid)
+{
+       struct drm_display_mode *newmode = NULL;
+       int count = 0, i = 0, ret_count = 0;
+       u8 *default_edid = (u8 *)edid;
+       static otm_hdmi_timing_t pdt[30];
+
+       if (connector == NULL || edid == NULL)
+               return 0;
+
+       for (i = 1; i <= default_edid[0x7e]; i++) {
+               u8 *ext = default_edid + (i * EDID_LENGTH);
+               switch (*ext) {
+               case CEA_EXT:
+                       count += otm_hdmi_timing_from_cea_modes(ext,
+                                                               &pdt[count]);
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       /* Do Mapping from PDT to drm_display_mode */
+       for (i = 0; i < count; i++) {
+               newmode = android_hdmi_get_drm_mode_from_pdt(&pdt[i],
+                                                            connector->dev);
+               if (!newmode)
+                       continue;
+               drm_mode_probed_add(connector, newmode);
+               ret_count++;
+       }
+
+       return ret_count;
+}
+
+#ifdef OTM_HDMI_UNIT_TEST
+static bool android_hdmi_probed_mode_exists(
+                               struct drm_connector *connector,
+                               int hdisplay, int vdisplay, int vrefresh)
+{
+       struct drm_display_mode *mode, *t;
+       if (!connector || hdisplay < 0 || vdisplay < 0 || vrefresh < 0)
+               goto exit;
+
+       /* loop through all probed modes to match */
+       list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
+               if (mode->hdisplay == hdisplay &&
+                       mode->vdisplay == vdisplay &&
+                       vrefresh == drm_mode_vrefresh(mode)) {
+                       return true;
+               }
+       }
+exit:
+       return false;
+}
+
+static bool android_hdmi_add_noedid_mode(
+                               void *context,
+                               struct drm_connector *connector,
+                               int hdisplay, int vdisplay, int vrefresh)
+{
+       struct drm_display_mode *newmode = NULL;
+       otm_hdmi_timing_t *pdt = NULL;
+
+       if (!context || !connector || hdisplay < 0 ||
+                       vdisplay < 0 || vrefresh < 0)
+               goto exit;
+
+       /* get mode timings */
+       pdt = otm_hdmi_get_mode_timings(context, hdisplay, vdisplay, vrefresh);
+       if (!pdt)
+               goto exit;
+
+       /* add mode */
+       newmode = android_hdmi_get_drm_mode_from_pdt(pdt, connector->dev);
+       if (newmode) {
+               drm_mode_probed_add(connector, newmode);
+               return true;
+       }
+exit:
+       return false;
+}
+#endif
+
+/* Calculate refresh rate from mode */
+static int calculate_refresh_rate(struct drm_display_mode *mode)
+{
+       int refresh_rate = 0;
+
+       if (!mode)
+               return refresh_rate;
+
+       refresh_rate = (((mode->flags & DRM_MODE_FLAG_INTERLACE) ? 2 : 1) *
+                       mode->clock * 1000) /
+                       (mode->htotal * mode->vtotal);
+
+       return refresh_rate;
+}
+
+int android_hdmi_get_modes(struct drm_connector *connector)
+{
+       struct drm_device *dev = connector->dev;
+       struct drm_psb_private *dev_priv = dev->dev_private;
+       struct android_hdmi_priv *hdmi_priv = dev_priv->hdmi_priv;
+       struct edid *edid = NULL;
+       /* Edid address in HDMI context */
+       struct edid *ctx_edid = NULL;
+       struct drm_display_mode *mode, *t;
+       int i = 0, j = 0, ret = 0;
+       int refresh_rate = 0;
+       int pref_mode_found = -1;
+       debug_modes_count = 0;
+       struct i2c_adapter *adapter = NULL;
+#ifndef OTM_HDMI_FIXME
+       /* OTM_HDMI_FIXME: this should be from get attribute interface */
+       int adapter_num = 3;
+#endif
+       pr_debug("%s E\n", __func__);
+
+       /* Lazy edid read feature, which can save I2C transactions largely.
+        * Basically, HPD will do edid read and store to HDMI context.
+        * Therefore, get modes should read edid with the condition
+        * whether the edid is ready in HDP or not in a lazy way. */
+       if (edid_ready_in_hpd)
+               goto edid_is_ready;
+
+       adapter = i2c_get_adapter(adapter_num);
+
+       /* FIXME: drm_get_edid cause the system hung at DV1 boot up */
+       /* Read edid blocks from i2c device */
+       if (NULL != adapter)
+               edid = (struct edid *)drm_get_edid(connector, adapter);
+
+       if (edid == NULL) {
+               pr_err("%s Edid Read failed -use default edid", __func__);
+               /* OTM_HDMI_FIXME: this should provide by OTM */
+               edid = (struct edid *)default_edid;
+       } else
+               pr_debug("Edid Read Done in get modes\n");
+
+       /* Store raw edid into HDMI context */
+       otm_hdmi_set_raw_edid(hdmi_priv->context, (char *)edid);
+
+       /* Release edid */
+       if (edid && ((unsigned char *)edid != (unsigned char *)default_edid))
+               kfree(edid);
+
+edid_is_ready:
+       /* Get the edid stored in HDMI context */
+       otm_hdmi_get_raw_edid(hdmi_priv->context, (char **)&ctx_edid);
+
+       /* Parse the edid */
+       otm_hdmi_edid_parse(hdmi_priv->context, OTM_HDMI_USE_EDID_REAL);
+
+       /* Add modes into DRM mode list */
+       drm_mode_connector_update_edid_property(connector, ctx_edid);
+       ret = drm_add_edid_modes(connector, ctx_edid);
+       ret += android_hdmi_add_cea_edid_modes(connector, ctx_edid);
+
+#ifdef OTM_HDMI_UNIT_TEST
+       if (1 == cmdline_mode.specified) {
+               /* Add cmdline mode if it does not exist in EDID */
+               if (!android_hdmi_probed_mode_exists(connector,
+                       cmdline_mode.hdisplay,
+                       cmdline_mode.vdisplay,
+                       cmdline_mode.refresh))
+                       if (android_hdmi_add_noedid_mode(
+                               hdmi_priv->context,
+                               connector,
+                               cmdline_mode.hdisplay,
+                               cmdline_mode.vdisplay,
+                               cmdline_mode.refresh))
+                               ret++;
+       }
+#endif
+       connector->display_info.raw_edid = NULL;
+       /* TODO: MUST REVERT
+        * monitor_type is being used by mdfld_hdmi_set_property
+        * to switch state between HDMI & DVI
+        * That mechnism will be changed to use get attribute
+        * and at that time this code must be removed */
+       if (otm_hdmi_is_monitor_hdmi(hdmi_priv->context))
+               hdmi_priv->monitor_type = 1;/* MONITOR_TYPE_HDMI */
+       else
+               hdmi_priv->monitor_type = 2;/* MONITOR_TYPE_DVI */
+
+       j = 0;
+       list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
+               refresh_rate = calculate_refresh_rate(mode);
+               pr_debug("Mode %02d: %s %dHz\t Clk: %dKHz H/V: %c,%c"
+                       "flags: 0x%08x",
+                       j, mode->name, refresh_rate, mode->clock,
+                       (mode->flags & DRM_MODE_FLAG_PHSYNC) ? '+' : '-',
+                       (mode->flags & DRM_MODE_FLAG_PVSYNC) ? '+' : '-',
+                       mode->flags);
+
+       if (debug_modes_count < DEBUG_MODES) {
+               strncpy(arr_modes[debug_modes_count].name, mode->name,
+                       strlen(mode->name));
+               arr_modes[debug_modes_count].name[strlen(mode->name)] = '\0';
+               arr_modes[debug_modes_count].frq = refresh_rate;
+               arr_modes[debug_modes_count].clk = mode->clock;
+               debug_modes_count++;
+       } else {
+               pr_err("Increase size of DEBUG_MODES, some modes not"
+                        " listed in report_edid.sh\n");
+       }
+
+#ifdef OTM_HDMI_FIXME
+               /*
+                * prune modes that don't have proper stall values
+                */
+               if (otm_hdmi_is_monitor_hdmi(hdmi_priv->context) &&
+                       (get_stall_value(mode) == -1)) {
+                       pr_debug("%s: mode %dx%d@%dHz don't have stall"
+                               " value configured\n", __func__,
+                               mode->hdisplay, mode->vdisplay,
+                               refresh_rate);
+                       i++;
+                       drm_mode_remove(connector, mode);
+               }
+#endif
+               j++;
+       }
+
+       /* choose a preferred mode and set the mode type accordingly */
+       list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
+               /* check whether the display has support for 720P.
+                * 720P is the minimum requirement expected from
+                * external display.
+                * (extend this if condition to set other modes as preferred).
+                */
+               refresh_rate = calculate_refresh_rate(mode);
+               if (otm_hdmi_is_preferred_mode(mode->hdisplay, mode->vdisplay,
+                                               refresh_rate)) {
+                       pr_debug("External display has %dx%d support\n",
+                               mode->hdisplay, mode->vdisplay);
+                       mode->type |= DRM_MODE_TYPE_PREFERRED;
+                       pref_mode_found = 1;
+                       break;
+               }
+       }
+
+       /* clear any other preferred modes*/
+       if (pref_mode_found == 1) {
+               list_for_each_entry_safe(mode, t, &connector->probed_modes,
+                                        head) {
+                       refresh_rate = calculate_refresh_rate(mode);
+                       if (otm_hdmi_is_preferred_mode(mode->hdisplay,
+                                                      mode->vdisplay,
+                                                      refresh_rate))
+                               continue;
+                       mode->type &= ~DRM_MODE_TYPE_PREFERRED;
+               }
+       }
+
+       pr_debug("%s X (%d)", __func__, (ret - i));
+
+       return ret - i;
+}
+
+/*
+ * Description: helper function to print the display mode details.
+ *
+ * @mode:              drm display mode to print
+ *
+ * Returns:    none.
+ */
+static void __android_hdmi_dump_crtc_mode(struct drm_display_mode *mode)
+{
+       if (mode == NULL)
+               return;
+
+       pr_debug("hdisplay = %d\n", mode->hdisplay);
+       pr_debug("vdisplay = %d\n", mode->vdisplay);
+       pr_debug("hsync_start = %d\n", mode->hsync_start);
+       pr_debug("hsync_end = %d\n", mode->hsync_end);
+       pr_debug("htotal = %d\n", mode->htotal);
+       pr_debug("vsync_start = %d\n", mode->vsync_start);
+       pr_debug("vsync_end = %d\n", mode->vsync_end);
+       pr_debug("vtotal = %d\n", mode->vtotal);
+       pr_debug("clock = %d\n", mode->clock);
+       pr_debug("flags = 0x%x\n", mode->flags);
+}
+
+/* Derive 59.94Hz dot clock from 60Hz dot clock
+ */
+static int __f5994(int dotclock)
+{
+       return DIV_ROUND_UP(dotclock*1000, 1001);
+}
+
+/*
+ * Description: helper function to convert drm_display_mode to
+ *             otm_hdmi_timing.
+ *
+ * @otm_mode:          otm hdmi mode to be populated
+ * @drm_mode:          drm_display_mode
+ *
+ * Returns:    none.
+ */
+static void __android_hdmi_drm_mode_to_otm_timing(otm_hdmi_timing_t *otm_mode,
+                               struct drm_display_mode *drm_mode)
+{
+       uint8_t i = 0;
+
+       if (otm_mode == NULL || drm_mode == NULL)
+               return;
+
+       otm_mode->width                 = (unsigned short)
+                                               drm_mode->crtc_hdisplay;
+       otm_mode->height                = (unsigned short)
+                                               drm_mode->crtc_vdisplay;
+       otm_mode->dclk                  = (unsigned long)
+                                               drm_mode->clock;
+       otm_mode->htotal                = (unsigned short)
+                                               drm_mode->crtc_htotal;
+       otm_mode->hblank_start          = (unsigned short)
+                                               drm_mode->crtc_hblank_start;
+       otm_mode->hblank_end            = (unsigned short)
+                                               drm_mode->crtc_hblank_end;
+       otm_mode->hsync_start           = (unsigned short)
+                                               drm_mode->crtc_hsync_start;
+       otm_mode->hsync_end             = (unsigned short)
+                                               drm_mode->crtc_hsync_end;
+       otm_mode->vtotal                = (unsigned short)
+                                               drm_mode->crtc_vtotal;
+       otm_mode->vblank_start          = (unsigned short)
+                                               drm_mode->crtc_vblank_start;
+       otm_mode->vblank_end            = (unsigned short)
+                                               drm_mode->crtc_vblank_end;
+       otm_mode->vsync_start           = (unsigned short)
+                                               drm_mode->crtc_vsync_start;
+       otm_mode->vsync_end             = (unsigned short)
+                                               drm_mode->crtc_vsync_end;
+       otm_mode->mode_info_flags       = (unsigned long)
+                                               drm_mode->flags;
+
+       /* TODO: metadata should be populated using table from mode_info.c */
+       otm_mode->metadata = 0;
+       for (i = 0; i < ARRAY_SIZE(vic_formats); i++) {
+               if (otm_mode->width == vic_formats[i].width &&
+                  otm_mode->height == vic_formats[i].height &&
+                  otm_mode->htotal == vic_formats[i].htotal &&
+                  otm_mode->vtotal == vic_formats[i].vtotal &&
+                  (otm_mode->dclk == vic_formats[i].dclk ||
+                   otm_mode->dclk == __f5994(vic_formats[i].dclk))) {
+                       if (1 == cmdline_mode.specified &&
+                           1 == cmdline_mode.vic_specified) {
+                               if (cmdline_mode.vic == vic_formats[i].vic) {
+                                       otm_mode->metadata = cmdline_mode.vic;
+                                       break;
+                               }
+                               /* else continue */
+                       } else {
+                               otm_mode->metadata = vic_formats[i].vic;
+                               break;
+                       }
+               }
+       }
+}
+
+/* TODO: get these values depending on the platform */
+#define OTM_HDMI_MDFLD_MIPI_NATIVE_HDISPLAY 1280
+#define OTM_HDMI_MDFLD_MIPI_NATIVE_VDISPLAY 800
+#define OTM_HDMI_MDFLD_PFIT_WIDTH_LIMIT 1024
+
+/*
+ * Description: crtc mode set for hdmi pipe.
+ *
+ * @crtc:              crtc
+ * @mode:              mode requested
+ * @adjusted_mode:     adjusted mode
+ * @x, y, old_fb:      old frame buffer values used for flushing old plane.
+ *
+ * Returns:    0 on success
+ *             -EINVAL on NULL input arguments
+ */
+int android_hdmi_crtc_mode_set(struct drm_crtc *crtc,
+                               struct drm_display_mode *mode,
+                               struct drm_display_mode *adjusted_mode,
+                               int x, int y,
+                               struct drm_framebuffer *old_fb)
+{
+       struct drm_device *dev;
+       struct psb_intel_crtc *psb_intel_crtc;
+       struct drm_psb_private *dev_priv;
+       struct drm_framebuffer *fb;
+       struct android_hdmi_priv *hdmi_priv;
+       struct drm_mode_config *mode_config;
+       struct psb_intel_output *psb_intel_output = NULL;
+       struct drm_encoder *encoder;
+       struct drm_connector *connector;
+       uint64_t scalingType = DRM_MODE_SCALE_CENTER;
+       int pipe;
+       otm_hdmi_timing_t otm_mode, otm_adjusted_mode;
+       uint32_t clock_khz;
+       int fb_width, fb_height;
+#ifndef MFLD_HDMI_PR3
+       u32 width_align, pipebstride;
+#endif
+       pr_debug("%s E", __func__);
+
+       if (crtc == NULL || mode == NULL || adjusted_mode == NULL)
+               return -EINVAL;
+
+       /* get handles for required data */
+       dev = crtc->dev;
+       psb_intel_crtc = to_psb_intel_crtc(crtc);
+       pipe = psb_intel_crtc->pipe;
+       dev_priv = dev->dev_private;
+       fb = crtc->fb;
+       fb_width = fb->width;
+       fb_height = fb->height;
+       hdmi_priv = dev_priv->hdmi_priv;
+       mode_config = &dev->mode_config;
+
+       if (pipe != 1) {
+               pr_err("%s: Invalid pipe %d", __func__, pipe);
+               return 0;
+       }
+
+       pr_debug("%s mode info:\n", __func__);
+       __android_hdmi_dump_crtc_mode(mode);
+       pr_debug("%s adjusted mode info:\n", __func__);
+       __android_hdmi_dump_crtc_mode(adjusted_mode);
+
+       memcpy(&psb_intel_crtc->saved_mode, mode,
+                               sizeof(struct drm_display_mode));
+       memcpy(&psb_intel_crtc->saved_adjusted_mode, adjusted_mode,
+                               sizeof(struct drm_display_mode));
+
+       __android_hdmi_drm_mode_to_otm_timing(&otm_mode, mode);
+       __android_hdmi_drm_mode_to_otm_timing(&otm_adjusted_mode,
+                                               adjusted_mode);
+
+#ifdef MFLD_HDMI_PR3
+       list_for_each_entry(connector, &mode_config->connector_list, head) {
+               if (!connector)
+                       continue;
+               encoder = connector->encoder;
+               if (!encoder)
+                       continue;
+               if (encoder->crtc != crtc)
+                       continue;
+               psb_intel_output = to_psb_intel_output(connector);
+       }
+
+       if (psb_intel_output)
+               drm_connector_property_get_value(&psb_intel_output->base,
+                       dev->mode_config.scaling_mode_property, &scalingType);
+
+       psb_intel_crtc->scaling_type = scalingType;
+#endif
+       /* Disable the VGA plane that we never use */
+       REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
+
+       /* Disable the panel fitter if it was on our pipe */
+       /* TODO: do this down the layers. */
+       if (psb_intel_panel_fitter_pipe(dev) == pipe)
+               REG_WRITE(PFIT_CONTROL, 0);
+
+       /* Flush the plane changes */
+       {
+               struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+               crtc_funcs->mode_set_base(crtc, x, y, old_fb);
+       }
+
+#if !defined(MFLD_HDMI_PR3) && !defined(MFLD_HDMI_DV1)
+       if (OTM_HDMI_MDFLD_MIPI_NATIVE_HDISPLAY == fb->width
+               && otm_adjusted_mode.width < OTM_HDMI_MDFLD_PFIT_WIDTH_LIMIT) {
+               /* setup HDMI buffers for SW downscaling.
+                * The scenario where this SW downscaling will be executed has
+                * a very low probability. The likely scenario is, where the
+                * external display can only support modes less than
+                * 1024x768, which has very less probability, as most of the
+                * monitors has atleast 1024x768 support.
+                */
+               android_hdmi_setup_hdmibuffers(dev, otm_adjusted_mode.width,
+                       otm_adjusted_mode.height, 2,
+                       fb->bits_per_pixel, fb->width, fb->height);
+
+               width_align = (otm_adjusted_mode.width + 31) & ~31;
+               pipebstride = 4 * width_align;
+               REG_WRITE(DSPBSTRIDE, pipebstride);
+               fb_width = otm_adjusted_mode.width;
+               fb_height = otm_adjusted_mode.height;
+       }
+#endif
+
+       /*
+        * TODO: clock_khz: is used in mdfld_hdmi_audio.c
+        * while returning hdmi audio capabilities.
+        * remove this field from mode_set interfaces and move
+        * into audio interfaces of OTM when implemented
+        */
+       if (otm_hdmi_crtc_mode_set(hdmi_priv->context, &otm_mode,
+                               &otm_adjusted_mode, fb_width,
+                               fb_height, &clock_khz)) {
+               pr_err("%s: failed to perform hdmi crtc mode set",
+                                       __func__);
+               return 0;
+       }
+
+       /*
+        * TODO: this field is used in mdfld_hdmi_audio.c
+        * while returning hdmi audio capabilities.
+        * Remove this and move into audio interfaces of OTM when implemented.
+        */
+       dev_priv->tmds_clock_khz = clock_khz;
+
+#ifdef MFLD_HDMI_PR3
+       /*
+        * SW workaround for Compliance 7-29 ACR test on 576p@50
+        * use the nominal pixel clock, instead of the actual clock
+        */
+       if (otm_adjusted_mode.metadata == 17 ||
+                       otm_adjusted_mode.metadata == 18)
+               dev_priv->tmds_clock_khz = otm_adjusted_mode.dclk;
+#endif
+
+       psb_intel_wait_for_vblank(dev);
+
+       pr_debug("%s X", __func__);
+       return 0;
+}
+
+/*
+ * Description: encoder mode set for hdmi pipe.
+ *
+ * @encoder:           hdmi encoder
+ * @mode:              mode requested
+ * @adjusted_mode:     adjusted mode
+ *
+ * Returns:    none.
+ */
+void android_hdmi_enc_mode_set(struct drm_encoder *encoder,
+                               struct drm_display_mode *mode,
+                               struct drm_display_mode *adjusted_mode)
+{
+       struct drm_device *dev;
+       struct android_hdmi_priv *hdmi_priv;
+       struct drm_psb_private *dev_priv;
+#ifdef CONFIG_SND_INTELMID_HDMI_AUDIO
+       void *had_pvt_data;
+       enum had_event_type event_type = HAD_EVENT_MODE_CHANGING;
+#endif
+       otm_hdmi_timing_t otm_mode, otm_adjusted_mode;
+
+       pr_debug("%s E", __func__);
+
+       if (encoder == NULL || mode == NULL || adjusted_mode == NULL)
+               return;
+
+       /* get handles for required data */
+       dev = encoder->dev;
+       dev_priv = dev->dev_private;
+       hdmi_priv = dev_priv->hdmi_priv;
+#ifdef CONFIG_SND_INTELMID_HDMI_AUDIO
+       had_pvt_data = dev_priv->had_pvt_data;
+#endif
+
+       __android_hdmi_drm_mode_to_otm_timing(&otm_mode, mode);
+       __android_hdmi_drm_mode_to_otm_timing(&otm_adjusted_mode,
+                                               adjusted_mode);
+
+       if (otm_hdmi_enc_mode_set(hdmi_priv->context, &otm_mode,
+                               &otm_adjusted_mode)) {
+               pr_err("%s: failed to perform hdmi enc mode set",
+                                       __func__);
+               return;
+       }
+
+#ifdef CONFIG_SND_INTELMID_HDMI_AUDIO
+       /* Send MODE_CHANGE event to Audio driver */
+       if (dev_priv->mdfld_had_event_callbacks)
+               (*dev_priv->mdfld_had_event_callbacks)(event_type,
+                               had_pvt_data);
+#endif
+
+#ifdef OTM_HDMI_HDCP_ENABLE
+       /* enable hdcp */
+       if (otm_hdmi_hdcp_enable(hdmi_priv->context))
+               pr_debug("hdcp enabled");
+       else
+               pr_err("hdcp could not be enabled");
+#endif
+       return;
+}
+
+/*
+ * Description: save the register for HDMI display
+ *
+ * @dev:               drm device
+ *
+ * Returns:    none.
+ */
+void android_hdmi_save_display_registers(struct drm_device *dev)
+{
+       struct drm_psb_private *dev_priv;
+       struct android_hdmi_priv *hdmi_priv;
+       uint8_t data;
+       if (NULL == dev)
+               return;
+       dev_priv = dev->dev_private;
+       if (NULL == dev_priv)
+               return;
+       hdmi_priv = dev_priv->hdmi_priv;
+       if (NULL == hdmi_priv)
+               return;
+       /* TODO: get hpd status using get attribute */
+       /* Check if monitor is attached to HDMI connector. */
+       intel_scu_ipc_ioread8(MSIC_HDMI_STATUS, &data);
+       otm_hdmi_save_display_registers(hdmi_priv->context,
+                               (data & HPD_SIGNAL_STATUS));
+       return;
+}
+
+/*
+ * Description: restore the register and enable the HDMI display
+ *
+ * @dev:               drm device
+ *
+ * Returns:    none.
+ */
+void android_hdmi_restore_and_enable_display(struct drm_device *dev)
+{
+       struct drm_psb_private *dev_priv;
+       struct android_hdmi_priv *hdmi_priv;
+       uint8_t data;
+       if (NULL == dev)
+               return;
+       dev_priv = dev->dev_private;
+       if (NULL == dev_priv)
+               return;
+       hdmi_priv = dev_priv->hdmi_priv;
+       if (NULL == hdmi_priv)
+               return;
+       /* TODO: get hpd status using get attribute */
+       /* Check if monitor is attached to HDMI connector. */
+       intel_scu_ipc_ioread8(MSIC_HDMI_STATUS, &data);
+       otm_hdmi_restore_and_enable_display(hdmi_priv->context,
+                       (data & HPD_SIGNAL_STATUS));
+}
+
+/*
+ * Description: disable HDMI display
+ *
+ * @dev:               drm device
+ *
+ * Returns:    none.
+ */
+void android_disable_hdmi(struct drm_device *dev)
+{
+       struct drm_psb_private *dev_priv;
+       struct android_hdmi_priv *hdmi_priv;
+       if (NULL == dev)
+               return;
+       dev_priv = dev->dev_private;
+       if (NULL == dev_priv)
+               return;
+       hdmi_priv = dev_priv->hdmi_priv;
+       if (NULL == hdmi_priv)
+               return;
+       otm_disable_hdmi(hdmi_priv->context);
+       return;
+}
+
+/*
+ * Description: hdmi helper function to detect whether hdmi/dvi
+ *             is connected or not.
+ *
+ * @connector: hdmi connector
+ *
+ * Returns:    connector_status_connected if hdmi/dvi is connected.
+ *             connector_status_disconnected if hdmi/dvi is not connected.
+ */
+enum drm_connector_status android_hdmi_detect(struct drm_connector *connector)
+{
+       struct drm_device *dev = connector->dev;
+       struct drm_psb_private *dev_priv =
+               (struct drm_psb_private *)dev->dev_private;
+       struct android_hdmi_priv *hdmi_priv = dev_priv->hdmi_priv;
+       u8 data = 0;
+
+#ifndef OTM_HDMI_FIXME
+       /* OTM_HDMI_FIXME: this should be from get attribute interface */
+       int adapter_num = 3;
+#endif
+       struct i2c_adapter *adapter = i2c_get_adapter(adapter_num);
+
+       if (NULL == connector || NULL == adapter)
+               return connector_status_disconnected;
+
+       /* Check if monitor is attached to HDMI connector. */
+       intel_scu_ipc_ioread8(MSIC_HDMI_STATUS, &data);
+       pr_debug("%s: HPD connected data = 0x%x.\n", __func__, data);
+
+#ifdef OTM_HDMI_HDCP_ENABLE
+       otm_hdmi_hdcp_set_hpd_state(hdmi_priv->context,
+                               (data & HPD_SIGNAL_STATUS));
+#endif
+
+       if (data & HPD_SIGNAL_STATUS) {
+               /*
+                * Handle Hot-plug of HDMI. Display B would be power-gated
+                * by ospm_post_init if HDMI is not detected during driver load.
+                * This will power-up Display B if HDMI is
+                * connected post driver load.
+                */
+               /*
+                * If pmu_nc_set_power_state fails then accessing HW
+                * reg would result in a crash - IERR/Fabric error.
+                */
+               if (pmu_nc_set_power_state(OSPM_DISPLAY_B_ISLAND,
+                                       OSPM_ISLAND_UP, OSPM_REG_TYPE))
+                       BUG();
+
+               dev_priv->panel_desc |= DISPLAY_B;
+               return connector_status_connected;
+       } else {
+               /*
+                * Clean up the HDMI connector attached encoder, to make
+                * drm_crtc_helper_set_config() do mode setting each time,
+                * especially when plug out and plug in HDMI.
+                */
+               drm_helper_disable_unused_functions(dev);
+
+#ifdef OTM_HDMI_HDCP_ENABLE
+               /* TODO: HPD status should be used by HDCP through attributes */
+               if (otm_hdmi_hdcp_disable(hdmi_priv->context))
+                       pr_debug("hdcp disabled\n");
+               else
+                       pr_debug("failed to disable hdcp\n");
+#endif
+               return connector_status_disconnected;
+       }
+}
+
+/*
+ * Description: hdmi helper function to manage power to the display (dpms)
+ *
+ * @encoder:   hdmi encoder
+ * @mode:      dpms on or off
+ *
+ * Returns:    none
+ */
+void android_hdmi_dpms(struct drm_encoder *encoder, int mode)
+{
+       struct drm_device *dev;
+       struct drm_psb_private *dev_priv;
+       struct android_hdmi_priv *hdmi_priv;
+
+       if (encoder == NULL)
+               return;
+
+       dev = encoder->dev;
+       dev_priv = dev->dev_private;
+       hdmi_priv = dev_priv->hdmi_priv;
+
+       /* TODO: Move entire mdfld_hdmi_dpms function into OTM */
+#ifdef OTM_HDMI_HDCP_ENABLE
+       otm_hdmi_hdcp_set_dpms(hdmi_priv->context, (mode == DRM_MODE_DPMS_ON));
+#endif
+}
+
+/**
+ *
+ * Internal scripts wrapper functions.
+ *
+ */
+/*
+ * TODO: Remove this function afer EDID Parse
+ *      for established modes is implemented
+ */
+
+/* Starting this off, but all scripts/unit test helpers should move
+ * to another file.
+ */
+
+#ifdef OTM_HDMI_UNIT_TEST
+
+/**
+ *     test_otm_hdmi_report_edid_full() - Report current EDID information
+ *
+ *     This routine simply dumps the EDID information
+ *
+ *     Returns - nothing
+ */
+void test_otm_hdmi_report_edid_full()
+{
+       int i = 0;
+       printk(KERN_ALERT "\n*** Supported Modes ***\n");
+
+       for (i = 0; i < debug_modes_count; i++)
+               printk(KERN_ALERT "Mode %02d: %s @%dHz Clk: %dKHz\n", i,
+               arr_modes[i].name, arr_modes[i].frq, arr_modes[i].clk);
+
+       printk(KERN_ALERT "\n");
+}
+EXPORT_SYMBOL_GPL(test_otm_hdmi_report_edid_full);
+#endif
diff --git a/drivers/staging/mrst/drv/otm_hdmi/os/android/include/android_hdmi.h b/drivers/staging/mrst/drv/otm_hdmi/os/android/include/android_hdmi.h
new file mode 100644 (file)
index 0000000..bfa0cb2
--- /dev/null
@@ -0,0 +1,397 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+ * Neither the name of Intel Corporation nor the names of its
+   contributors may be used to endorse or promote products derived
+   from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef __ANDROID_HDMI_H
+#define __ANDROID_HDMI_H
+
+#include <linux/types.h>
+
+#define CEA_EXT     0x02
+#define VTB_EXT     0x10
+#define DI_EXT      0x40
+#define LS_EXT      0x50
+#define MI_EXT      0x60
+
+/* TODO: move cea_861b_adb_t and hdmi_eeld_t into PIL */
+/* Header = 4, Baseline Data = 80 and Vendor (INTEL) specific = 2 as per
+ * EELD spec
+ * 4 + 80 + = 84
+ */
+#define HDMI_EELD_SIZE 84
+typedef union _hdmi_eeld {
+       uint8_t eeld[HDMI_EELD_SIZE];
+       #pragma pack(1)
+       struct {
+               /* Byte[0] = ELD Version Number */
+               union {
+                       uint8_t   byte0;
+                       struct {
+                               uint8_t reserved:3; /* Reserf */
+                               uint8_t eld_ver:5; /* ELD Version Number */
+                                               /* 00000b - reserved
+                                                * 00001b - first rev
+                                                * 00010b:11111b - reserved
+                                                * for future
+                                                */
+                       };
+               };
+
+               /* Byte[1] = Vendor Version Field */
+               union {
+                       uint8_t vendor_version;
+                       struct {
+                               uint8_t reserved1:3;
+                               uint8_t veld_ver:5; /* Version number of the ELD
+                                                    * extension. This value is
+                                                    * provisioned and unique to
+                                                    * each vendor.
+                                                    */
+                       };
+               };
+
+               /* Byte[2] = Baseline Lenght field */
+               uint8_t baseline_eld_length; /* Length of the Baseline structure
+                                             * divided by Four.
+                                             */
+
+               /* Byte [3] = Reserved for future use */
+               uint8_t byte3;
+
+               /* Starting of the BaseLine EELD structure
+                * Byte[4] = Monitor Name Length
+                */
+               union {
+                       uint8_t byte4;
+                       struct {
+                               uint8_t mnl:5;
+                               uint8_t cea_edid_rev_id:3;
+                       };
+               };
+
+               /* Byte[5] = Capabilities */
+               union {
+                       uint8_t capabilities;
+                       struct {
+                               uint8_t hdcp:1; /* HDCP support */
+                               uint8_t ai_support:1;   /* AI support */
+                               uint8_t connection_type:2; /* Connection type
+                                                           * 00 - HDMI
+                                                           * 01 - DP
+                                                           * 10 -11  Reserved
+                                                           * for future
+                                                           * connection types
+                                                           */
+                               uint8_t sadc:4; /* Indicates number of 3 bytes
+                                                * Short Audio Descriptors.
+                                                */
+                       };
+               };
+
+               /* Byte[6] = Audio Synch Delay */
+               uint8_t audio_synch_delay; /* Amount of time reported by the
+                                           * sink that the video trails audio
+                                           * in milliseconds.
+                                           */
+
+               /* Byte[7] = Speaker Allocation Block */
+               union {
+                       uint8_t speaker_allocation_block;
+                       struct {
+                               uint8_t flr:1; /*Front Left and Right channels*/
+                               uint8_t lfe:1; /*Low Frequency Effect channel*/
+                               uint8_t fc:1;  /*Center transmission channel*/
+                               uint8_t rlr:1; /*Rear Left and Right channels*/
+                               uint8_t rc:1; /*Rear Center channel*/
+                               uint8_t flrc:1; /*Front left and Right of Center
+                                                *transmission channels
+                                                */
+                               uint8_t rlrc:1; /*Rear left and Right of Center
+                                                *transmission channels
+                                                */
+                               uint8_t reserved3:1; /* Reserved */
+                       };
+               };
+
+               /* Byte[8 - 15] - 8 Byte port identification value */
+               uint8_t port_id_value[8];
+
+               /* Byte[16 - 17] - 2 Byte Manufacturer ID */
+               uint8_t manufacturer_id[2];
+
+               /* Byte[18 - 19] - 2 Byte Product ID */
+               uint8_t product_id[2];
+
+               /* Byte [20-83] - 64 Bytes of BaseLine Data */
+               uint8_t mn_sand_sads[64]; /* This will include
+                                          * - ASCII string of Monitor name
+                                          * - List of 3 byte SADs
+                                          * - Zero padding
+                                          */
+
+               /* Vendor ELD Block should continue here!
+                * No Vendor ELD block defined as of now.
+                */
+       };
+       #pragma pack()
+} hdmi_eeld_t;
+
+typedef struct _cea_861b_adb {
+#pragma pack(1)
+       union {
+               uint8_t byte1;
+               struct {
+                       uint8_t   max_channels:3; /* Bits[0-2] */
+                       uint8_t   audio_format_code:4; /* Bits[3-6],
+                                                       see AUDIO_FORMAT_CODES*/
+                       uint8_t   b1reserved:1; /* Bit[7] - reserved */
+               };
+       };
+       union {
+               uint8_t byte2;
+               struct {
+                       uint8_t sp_rate_32kHz:1; /*Bit[0] sample rate=32kHz*/
+                       uint8_t sp_rate_44kHz:1; /*Bit[1] sample rate=44kHz*/
+                       uint8_t sp_rate_48kHz:1; /*Bit[2] sample rate=48kHz*/
+                       uint8_t sp_rate_88kHz:1; /*Bit[3] sample rate=88kHz*/
+                       uint8_t sp_rate_96kHz:1; /*Bit[4] sample rate=96kHz*/
+                       uint8_t sp_rate_176kHz:1; /*Bit[5] sample rate=176kHz*/
+                       uint8_t sp_rate_192kHz:1; /*Bit[6] sample rate=192kHz*/
+                       uint8_t sp_rate_b2reserved:1; /* Bit[7] - reserved*/
+               };
+       };
+       union {
+               uint8_t   byte3; /* maximum bit rate divided by 8kHz */
+               /* following is the format of 3rd byte for
+                * uncompressed(LPCM) audio
+                */
+               struct {
+                       uint8_t bit_rate_16bit:1;       /* Bit[0] */
+                       uint8_t bit_rate_20bit:1;       /* Bit[1] */
+                       uint8_t bit_rate_24bit:1;       /* Bit[2] */
+                       uint8_t bit_rate_b3reserved:5;  /* Bits[3-7] */
+               };
+       };
+#pragma pack()
+
+} cea_861b_adb_t;
+
+struct android_hdmi_priv {
+       /* common */
+       struct drm_device *dev;
+
+       /* oaktrail specific */
+       /* PCI related parameters are not needed to be exposed.
+        * Need to remove.
+        */
+       void *regs;
+       int dpms_mode;
+       struct hdmi_i2c_dev *i2c_dev;
+
+
+       /*medfield specific */
+       u32 hdmib_reg;
+       u32 save_HDMIB;
+       bool has_hdmi_sink;
+       /* Should set this when detect hotplug */
+       bool hdmi_device_connected;
+       struct mdfld_hdmi_i2c *i2c_bus;
+       /* EELD packet holder*/
+       hdmi_eeld_t eeld;
+       u32 hdmi_eeld_size;
+       cea_861b_adb_t lpcm_sad;
+       bool is_hdcp_supported;
+       struct i2c_adapter *hdmi_i2c_adapter;   /* for control functions */
+       /*TODO: remove this and use from context when set_property is
+        * implemented in OTM.
+        */
+       int monitor_type;
+       void *context;
+};
+
+/* Global devices for switch class used for hotplug notification */
+extern struct switch_dev g_switch_hdmi_dev;
+extern struct switch_dev g_switch_dvi_dev;
+
+/* TODO: remove this once all code moved into OTM */
+extern const struct drm_encoder_funcs psb_intel_lvds_enc_funcs;
+extern const struct drm_encoder_helper_funcs mdfld_hdmi_helper_funcs;
+extern const struct drm_connector_funcs mdfld_hdmi_connector_funcs;
+extern const struct drm_connector_helper_funcs
+                       mdfld_hdmi_connector_helper_funcs;
+
+extern void android_hdmi_driver_init(struct drm_device *dev,
+                                               void *mode_dev);
+
+extern void android_hdmi_enable_hotplug(struct drm_device *dev);
+
+extern void android_hdmi_driver_setup(struct drm_device *dev);
+
+extern void android_hdmi_context_init(void *context);
+
+extern int android_hdmi_mode_valid(struct drm_connector *connector,
+                                       struct drm_display_mode *mode);
+
+extern int android_hdmi_get_modes(struct drm_connector *connector);
+
+/*
+ * Description: crtc mode set for hdmi pipe.
+ *
+ * @crtc:              crtc
+ * @mode:              mode requested
+ * @adjusted_mode:     adjusted mode
+ * @x, y, old_fb:      old frame buffer values used for flushing old plane.
+ *
+ * Returns:    0 on success
+ *             -EINVAL on NULL input arguments
+ */
+extern int android_hdmi_crtc_mode_set(struct drm_crtc *crtc,
+                               struct drm_display_mode *mode,
+                               struct drm_display_mode *adjusted_mode,
+                               int x, int y,
+                               struct drm_framebuffer *old_fb);
+
+/*
+ * Description: encoder mode set for hdmi pipe.
+ *
+ * @encoder:           hdmi encoder
+ * @mode:              mode requested
+ * @adjusted_mode:     adjusted mode
+ *
+ * Returns:    none.
+ */
+extern void android_hdmi_enc_mode_set(struct drm_encoder *encoder,
+                               struct drm_display_mode *mode,
+                               struct drm_display_mode *adjusted_mode);
+
+/* TODO: do this down the layers. */
+extern int psb_intel_panel_fitter_pipe(struct drm_device *dev);
+
+/* TODO: medfiled specific */
+extern void mdfld_hdmi_audio_init(struct android_hdmi_priv *p_hdmi_priv);
+extern void mdfld_msic_init(struct android_hdmi_priv *p_hdmi_priv);
+
+/*
+ * Allocates the hdmi buffers of specified dimensions.
+ * Initializes Scaling related paramters.
+ * input parameters:
+ *     psDrmDev: Drm Device.
+ *     ui32HdmiWidth, ui32HdmiHeight: HDMI mode
+ *     ui32BufferCount,: number of HDMI buffers to allocate.
+ *     bpp: bits per pixel to consider for allocating the buffer.
+ *     ui32LvdsWidth, ui32LvdsHeight: Native display (LVDS) Mode.
+ * returns '0' on success and other values on failure.
+ */
+extern int android_hdmi_setup_hdmibuffers(struct drm_device *psDrmDev,
+                               u32 ui32HdmiWidth, u32 ui32HdmiHeight,
+                               u32 ui32BufferCount, int bpp, u32 ui32LvdsWidth,
+                               u32 ui32LvdsHeight);
+
+/*
+ * Store the HDMI registers and enable the display
+ * Input parameters:
+ *     psDrmDev: Drm Device.
+ * Returns: none
+ */
+extern void android_hdmi_restore_and_enable_display(struct drm_device *dev);
+
+/*
+ * Save the HDMI display registers
+ * Input parameters:
+ *     psDrmDev: Drm Device.
+ * Returns: none
+ */
+extern void android_hdmi_save_display_registers(struct drm_device *dev);
+
+/*
+ * disable HDMI display
+ * Input parameters:
+ *     psDrmDev: Drm Device.
+ * Returns: none
+ */
+extern void android_disable_hdmi(struct drm_device *dev);
+
+
+/*
+ * Description: hdmi helper function to detect whether hdmi/dvi
+ *             is connected or not.
+ *
+ * @connector: hdmi connector
+ *
+ * Returns:    connector_status_connected if hdmi/dvi is connected.
+ *             connector_status_disconnected if hdmi/dvi is not connected.
+ */
+extern enum drm_connector_status android_hdmi_detect(struct drm_connector
+                                                               *connector);
+
+/*
+ * Description: hdmi helper function to manage power to the display (dpms)
+ *
+ * @encoder:   hdmi encoder
+ * @mode:      dpms on or off
+ *
+ * Returns:    none
+ */
+extern void android_hdmi_dpms(struct drm_encoder *encoder,
+                               int mode);
+
+#endif /* __ANDROID_HDMI_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/common/edid.c b/drivers/staging/mrst/drv/otm_hdmi/pil/common/edid.c
new file mode 100644 (file)
index 0000000..3abc4e5
--- /dev/null
@@ -0,0 +1,1365 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include "otm_hdmi_types.h"
+#include "edid_internal.h"
+#include "hdmi_timings.h"
+
+
+/*
+ * Macro for error checking
+ */
+#define VERIFY(exp, rc, error, label) \
+       if (!(exp)) {                 \
+               rc = error;           \
+               goto label;           \
+       }
+
+#define VERIFY_QUICK(exp, label) \
+       if (!(exp)) {            \
+               goto label;      \
+       }
+
+/*
+ * Various constants
+ */
+#define EDID_SIGNATURE 0x00FFFFFFFFFFFF00ull
+
+/*
+ * Debug printing setup
+ */
+/* TODO: All printing should use one method,either PD_LOG_PRINT,
+ * EDID_PRINT, DRM printing, pr_debug. The solution should be run-time
+ * instead of compile-time switches. Will need some work to get
+ * that done. Deferring for the time-being. Keep EDID prints
+ * disabled as they are invoked on every DRM get_mode query
+ * and prove costly and add problems like slow, jittery playback */
+#ifndef OTM_HDMI_FIXME
+int EDID_PRINT(const char *fmt, ...)
+{
+       return 0;
+}
+#else
+int EDID_PRINT(const char *fmt, ...)
+{
+       va_list arg_list;
+
+       va_start(arg_list, fmt);
+       vprintk(fmt, arg_list);
+       va_end(arg_list);
+       return 0;
+}
+#endif
+
+/*
+ * Structure to keep state of read operation
+ */
+typedef struct {
+       unsigned char *buffer;
+       int position;
+} read_context_t;
+
+/*
+ * fetch_next_field()
+ */
+void fetch_next_field(void *dst, read_context_t *read_context,
+                               unsigned int size)
+{
+       unsigned char *b = read_context->buffer + read_context->position;
+
+       switch (size) {
+#ifdef __ORDER_MSB__
+       case 1:
+               *(unsigned char *)dst = *b;
+               break;
+
+       case 2:
+               *(unsigned short *)dst |= (unsigned short)*(b + 1) << 0;
+               *(unsigned short *)dst |= (unsigned short)*(b + 0) << 8;
+               break;
+
+       case 4:
+               *(unsigned int *)dst |= (unsigned int)*(b + 3) << 0;
+               *(unsigned int *)dst |= (unsigned int)*(b + 2) << 8;
+               *(unsigned int *)dst |= (unsigned int)*(b + 1) << 16;
+               *(unsigned int *)dst |= (unsigned int)*(b + 0) << 24;
+               break;
+
+       case 8:
+               *(unsigned long long *)dst |= (unsigned long long)*(b + 7) << 0;
+               *(unsigned long long *)dst |= (unsigned long long)*(b + 6) << 8;
+               *(unsigned long long *)dst |=
+                   (unsigned long long)*(b + 5) << 16;
+               *(unsigned long long *)dst |=
+                   (unsigned long long)*(b + 4) << 24;
+               *(unsigned long long *)dst |=
+                   (unsigned long long)*(b + 3) << 32;
+               *(unsigned long long *)dst |=
+                   (unsigned long long)*(b + 2) << 40;
+               *(unsigned long long *)dst |=
+                   (unsigned long long)*(b + 1) << 48;
+               *(unsigned long long *)dst |=
+                   (unsigned long long)*(b + 0) << 56;
+               break;
+#endif
+
+       default:
+               /*
+                * This is only for byte sequences with LSB order, or where
+                * where order does not matter
+                */
+               memcpy(dst, b, size);
+               break;
+       }
+
+       read_context->position += size;
+}
+
+/*
+ * fetch_generic_descriptor()
+ */
+void fetch_generic_descriptor(generic_descriptor_t *gd, read_context_t *rctx)
+{
+       fetch_next_field(&gd->flag_required, rctx, 2);
+       fetch_next_field(&gd->flag_reserved, rctx, 1);
+       fetch_next_field(&gd->data_type_tag, rctx, 1);
+       fetch_next_field(&gd->flag, rctx, 1);
+       fetch_next_field(&gd->payload, rctx, 13);
+}
+
+/*
+ * fetch_timing_descriptor()
+ */
+void fetch_timing_descriptor(timing_descriptor_t *td, read_context_t *rctx)
+{
+       fetch_next_field(&td->pixel_clock, rctx, 2);
+       fetch_next_field(&td->h_active, rctx, 1);
+       fetch_next_field(&td->h_blanking, rctx, 1);
+       fetch_next_field(&td->h_active_blanking_hb, rctx, 1);
+       fetch_next_field(&td->v_active, rctx, 1);
+       fetch_next_field(&td->v_blanking, rctx, 1);
+       fetch_next_field(&td->v_active_blanking_hb, rctx, 1);
+       fetch_next_field(&td->h_sync_offset, rctx, 1);
+       fetch_next_field(&td->h_sync_pulse_width, rctx, 1);
+       fetch_next_field(&td->vs_offset_pulse_width, rctx, 1);
+       fetch_next_field(&td->offset_pulse_width_hb, rctx, 1);
+       fetch_next_field(&td->h_image_size, rctx, 1);
+       fetch_next_field(&td->v_image_size, rctx, 1);
+       fetch_next_field(&td->hv_image_size, rctx, 1);
+       fetch_next_field(&td->h_border, rctx, 1);
+       fetch_next_field(&td->v_border, rctx, 1);
+       fetch_next_field(&td->flags, rctx, 1);
+}
+
+/*
+ * fetch_block_zero()
+ * - ebz : structure representing edid block zero to be filled in
+ * - data: buffer of 128 bytes containing raw edid data supplied by TV
+ */
+otm_hdmi_ret_t fetch_block_zero(edid_block_zero_t *ebz, unsigned char *data)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       read_context_t read_context = {data, 0};
+       read_context_t *rctx = &read_context;
+       int i;
+
+       VERIFY(ebz != NULL, rc, OTM_HDMI_ERR_NULL_ARG, exit);
+       VERIFY(data != NULL, rc, OTM_HDMI_ERR_NULL_ARG, exit);
+
+       /* EDID signature */
+       fetch_next_field(&ebz->signature, rctx, 8);
+
+       /* Manufacturer name id */
+       fetch_next_field(&ebz->manufacturer_id, rctx, 2);
+
+       /* Product code */
+       fetch_next_field(&ebz->product_code, rctx, 2);
+
+       /* Serial number */
+       fetch_next_field(&ebz->serial_number, rctx, 4);
+
+       /* Manufacture week */
+       fetch_next_field(&ebz->manufacture_week, rctx, 1);
+
+       /* Manufacture year */
+       fetch_next_field(&ebz->manufacture_year, rctx, 1);
+
+       /* EDID version */
+       fetch_next_field(&ebz->version, rctx, 1);
+
+       /* EDID revision */
+       fetch_next_field(&ebz->revision, rctx, 1);
+
+       /* Video input definition */
+       fetch_next_field(&ebz->video_input_definition, rctx, 1);
+
+       /* Max horizontal image size */
+       fetch_next_field(&ebz->max_horz_image_size, rctx, 1);
+
+       /* Max vertical image size*/
+       fetch_next_field(&ebz->max_vert_image_size, rctx, 1);
+
+       /* Gamma */
+       fetch_next_field(&ebz->gamma, rctx, 1);
+
+       /* Feature support */
+       fetch_next_field(&ebz->feature_support, rctx, 1);
+
+       /* Color characteristics */
+       fetch_next_field(&ebz->rg_lowbits, rctx, 1);
+       fetch_next_field(&ebz->bw_lowbits, rctx, 1);
+       fetch_next_field(&ebz->red_x, rctx, 1);
+       fetch_next_field(&ebz->red_y, rctx, 1);
+       fetch_next_field(&ebz->green_x, rctx, 1);
+       fetch_next_field(&ebz->green_y, rctx, 1);
+       fetch_next_field(&ebz->blue_x, rctx, 1);
+       fetch_next_field(&ebz->blue_y, rctx, 1);
+       fetch_next_field(&ebz->white_x, rctx, 1);
+       fetch_next_field(&ebz->white_x, rctx, 1);
+
+       /* Established timings */
+       fetch_next_field(&ebz->est_timing_1, rctx, 1);
+       fetch_next_field(&ebz->est_timing_2, rctx, 1);
+       fetch_next_field(&ebz->est_timing_3, rctx, 1);
+
+       /* Standard timings */
+       for (i = 0; i < EDID_STD_TIMINGS_NUM; i++)
+               fetch_next_field(&ebz->std_timings[i], rctx, 2);
+
+       /* Detailed timing descriptors 1 and 2 */
+       fetch_generic_descriptor((generic_descriptor_t *) &ebz->td_1, rctx);
+       fetch_generic_descriptor((generic_descriptor_t *) &ebz->td_2, rctx);
+
+       /* Monitor Descriptors 1 and 2 */
+       fetch_generic_descriptor((generic_descriptor_t *) &ebz->md_1, rctx);
+       fetch_generic_descriptor((generic_descriptor_t *) &ebz->md_2, rctx);
+
+       /* Number of 128 byte blocks to follow */
+       fetch_next_field(&ebz->num_extentions, rctx, 1);
+
+exit:
+       return rc;
+}
+
+/*
+ * fetch_extension_block_cea()
+ */
+otm_hdmi_ret_t fetch_extension_block_cea(extention_block_cea_t *eb,
+                                   unsigned char *data)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       read_context_t read_context = {data, 0};
+       read_context_t *rctx = &read_context;
+
+       VERIFY(eb != NULL, rc, OTM_HDMI_ERR_NULL_ARG, exit);
+       VERIFY(data != NULL, rc, OTM_HDMI_ERR_NULL_ARG, exit);
+
+       fetch_next_field(&eb->tag, rctx, 1);
+       fetch_next_field(&eb->revision, rctx, 1);
+       fetch_next_field(&eb->content_offset, rctx, 1);
+       fetch_next_field(&eb->flags, rctx, 1);
+       fetch_next_field(&eb->data, rctx, 124);
+
+exit:
+       return rc;
+}
+
+/*
+ * encode_refresh()
+ * Convert an integer refresh rate to the equivalent enumeration
+ */
+static otm_hdmi_refresh_t encode_refresh(unsigned refresh)
+{
+       /* Both 1/1001 and 1/1000 refresh rates are included in case
+        * EDID contains 1/1001 pixel clock values in the entry
+        */
+       switch (refresh) {
+       case 23:
+               return OTM_HDMI_REFRESH_24;
+       case 24:
+               return OTM_HDMI_REFRESH_24;
+       case 25:
+               return OTM_HDMI_REFRESH_25;
+       case 29:
+               return OTM_HDMI_REFRESH_30;
+       case 30:
+               return OTM_HDMI_REFRESH_30;
+       case 50:
+               return OTM_HDMI_REFRESH_50;
+       case 59:
+               return OTM_HDMI_REFRESH_60;
+       case 60:
+               return OTM_HDMI_REFRESH_60;
+       }
+       return OTM_HDMI_REFRESH_USER_DEFINED;
+}
+
+/*
+ * Returns index of timing with given VIC in given table; -1 otherwise
+ */
+int find_timing_by_vic_tp(const otm_hdmi_timing_t **set, int size,
+                                               unsigned int vic)
+{
+       int i, rc = -1;
+
+       VERIFY(set, rc, -1, exit);
+
+       for (i = 0; i < size; i++) {
+               if (set[i]->metadata == vic) {
+                       rc = i;
+                       break;
+               }
+       }
+
+exit:
+       return rc;
+}
+
+/*
+ * Timings comparison
+ */
+static bool __timing_equal(const otm_hdmi_timing_t *t1,
+                                   const otm_hdmi_timing_t *t2)
+{
+       unsigned int t1_flags = t1->mode_info_flags & PD_SCAN_INTERLACE;
+       unsigned int t2_flags = t2->mode_info_flags & PD_SCAN_INTERLACE;
+
+       return ((t1->width == t2->width) &&
+               (t1->height == t2->height) &&
+               (t1->refresh == t2->refresh) &&
+               (t1_flags == t2_flags) && (t1->stereo_type == t2->stereo_type));
+}
+
+/*
+ * Returns index of given timings in given table of timings; -1 otherwise
+ */
+int find_timing(const otm_hdmi_timing_t *set, int size,
+                                       const otm_hdmi_timing_t *e)
+{
+       int i, rc = -1;
+       VERIFY(set && e, rc, -1, exit);
+       for (i = 0; i < size && !__timing_equal(&set[i], e); i++);
+               
+       rc = (i < size) ? i : -1;
+exit:
+       return rc;
+}
+
+/*
+ * Returns index of given timings in given table of timing pointers;
+ * -1 otherwise
+ */
+int find_timing_tp(const otm_hdmi_timing_t **set, int size,
+                                       const otm_hdmi_timing_t *e)
+{
+       int i, rc = -1;
+       VERIFY(set && e, rc, -1, exit);
+       for (i = 0; i < size && !__timing_equal(set[i], e); i++);
+               
+       rc = (i < size) ? i : -1;
+exit:
+       return rc;
+}
+
+/*
+ * add_timings()
+ */
+otm_hdmi_ret_t add_timings(edid_info_t *edid, const otm_hdmi_timing_t *pdt,
+                                               unsigned int order)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       int i, j;
+
+       /* Safety checks */
+       VERIFY((edid != NULL) && (pdt != NULL), rc,
+                               OTM_HDMI_ERR_NULL_ARG, exit);
+
+       /* Is there room for more timings at all? */
+       VERIFY(edid->num_timings < MAX_TIMINGS, rc,
+                               OTM_HDMI_ERR_INVAL, exit);
+
+       /* Print info about it */
+       print_pd_timing(pdt, order, EDID_PRINT);
+
+       /* Do not add modes that we dont support */
+       i = find_timing_tp(edid->ref_timings, edid->num_ref_timings, pdt);
+       VERIFY(i > -1, rc, OTM_HDMI_ERR_INVAL, exit);
+
+       /* Do not add duplicates; Update discovery order though for cases when
+        * a mode was decoded from DTD first
+        */
+       if ((j = find_timing(edid->timings, edid->num_timings, pdt)) != -1) {
+               edid->order[j] = !edid->order[j] ? order : edid->order[j];
+               goto exit;
+       }
+       /* Save discovery order */
+       edid->order[edid->num_timings] = order;
+
+       /* Add timing */
+       edid->timings[edid->num_timings++] = *edid->ref_timings[i];
+
+       /* Update supported family of refresh rates */
+       edid->supports_60Hz = edid->supports_60Hz
+           || pdt->refresh == OTM_HDMI_REFRESH_60;
+       edid->supports_50Hz = edid->supports_50Hz
+           || pdt->refresh == OTM_HDMI_REFRESH_50;
+
+exit:
+       return rc;
+}
+
+/*
+ * checksum_valid()
+ */
+bool checksum_valid(unsigned char *buffer, int size)
+{
+       unsigned char sum_computed = 0;
+
+       while (size-- > 0)
+               sum_computed += *(buffer++);
+
+       return (sum_computed == 0) ? true : false;
+}
+
+/*
+ * decode_speaker_allocation_data_block()
+ */
+void decode_speaker_allocation_data_block(unsigned char *e, int n,
+                                       edid_info_t *edid)
+{
+       int ne = n / 3;
+
+       EDID_PRINT("[speaker block]\n");
+
+       while (ne-- > 0) {
+               edid->speaker_map =
+                   (unsigned)*e | (unsigned)(*(e + 1) & 0x7) << 8;
+               print_speaker_layout(edid->speaker_map, EDID_PRINT);
+               e++;
+               e++;             /* skip the rest of the block */
+       }
+}
+
+/*
+ * decode_video_data_block()
+ */
+void decode_video_data_block(unsigned char *e, int n, edid_info_t *edid)
+{
+       int vic, j, i = 0;
+
+       EDID_PRINT("[video data block]\n");
+
+       while (n-- > 0) {
+               vic = *e & 0x7F;
+               EDID_PRINT("- mode #%d %s\n", vic, (*e & 0x80) ? "native" : "");
+
+               if ((j =
+                    find_timing_by_vic_tp(edid->ref_timings,
+                                          edid->num_ref_timings, vic)) != -1) {
+                       add_timings(edid, edid->ref_timings[j], ++i);
+
+                        /* Handle native mode */
+                       if (*e & 0x80) {
+                               edid->native_idx =
+                                   find_timing(edid->timings,
+                                               edid->num_timings,
+                                               edid->ref_timings[j]);
+                       }
+               }
+               e++;
+       }
+}
+
+/*
+ * decode_audio_data_block()
+ */
+void decode_audio_data_block(unsigned char *e, int n, edid_info_t *edid)
+{
+       int ne = n / 3;
+       otm_hdmi_audio_cap_t *adb = (otm_hdmi_audio_cap_t *) &edid->audio_caps;
+
+       EDID_PRINT("[audio data block... %d entries]\n", ne);
+
+       while (ne-- > 0) {
+               /* Do we have room for another capability? */
+               if (edid->num_caps < MAX_CAPS) {
+                       adb[edid->num_caps].format = (*e & 0x78) >> 3;
+                       adb[edid->num_caps].max_channels = (*e & 0x07) + 1;
+                       adb[edid->num_caps].fs = *(e + 1) & 0x7F;
+                       adb[edid->num_caps].ss_bitrate = *(e + 2);
+                       print_audio_capability(&adb[edid->num_caps],
+                                              EDID_PRINT);
+                       edid->num_caps++;
+               }
+               /* Go to the next entry of the block */
+               e += 3;
+       }
+}
+
+/*
+ *
+ */
+void declare_mandatory_3d(edid_info_t *edid)
+{
+       if (true) {
+               add_timings(edid, &MODE_1920x1080p24__FP2, 0);
+               add_timings(edid, &MODE_1920x1080p24__FP, 0);
+               add_timings(edid, &MODE_1920x1080p24__TBH2, 0);
+       }
+
+       if (edid->supports_60Hz) {
+               add_timings(edid, &MODE_1280x720p5994_60__FP2, 0);
+               add_timings(edid, &MODE_1280x720p5994_60__FP, 0);
+               add_timings(edid, &MODE_1920x1080i5994_60__SBSH2, 0);
+               add_timings(edid, &MODE_1280x720p5994_60__TBH2, 0);
+       }
+
+       if (edid->supports_50Hz) {
+               add_timings(edid, &MODE_1280x720p50__FP2, 0);
+               add_timings(edid, &MODE_1280x720p50__FP, 0);
+               add_timings(edid, &MODE_1920x1080i50__SBSH2, 0);
+               add_timings(edid, &MODE_1280x720p50__TBH2, 0);
+       }
+};
+
+/*
+ * Addition of 3D timing via 2D mode
+ */
+void add_3d_mode_via_2d(unsigned int vic, unsigned int struc_3d,
+                                               edid_info_t *edid)
+{
+       unsigned int j, k, num_timings = edid->num_timings;
+       otm_hdmi_timing_t t;
+
+       struct {
+               unsigned int struc;
+               unsigned int type;
+       } details_3d[] = {
+               {
+               0x00, OTM_HDMI_STEREO_FRAME_PACKING_2}, {
+               0x00, OTM_HDMI_STEREO_FRAME_PACKING}, {
+               0x06, OTM_HDMI_STEREO_TOP_BOTTOM_HALF_2}, {
+       0x08, OTM_HDMI_STEREO_SIDE_BY_SIDE_HALF_2},};
+
+       /* Look for an entry with given order among all decoded 2D timings */
+       for (j = 0; j < num_timings; j++) {
+               if (edid->order[j] == vic) {
+                       /*
+                        * Create all required 3D variations for given
+                        * 2D mode
+                        */
+                       for (k = 0;
+                            k < sizeof(details_3d) / sizeof(*details_3d);
+                            k++) {
+                               if (details_3d[k].struc == struc_3d) {
+                                       t = edid->timings[j];
+                                       t.stereo_type = details_3d[k].type;
+                                       add_timings(edid, &t, 0);
+                               }
+                       }
+
+                       /* Entry of given order was found so start looking for
+                        * new one
+                        */
+                       break;
+               }
+       }
+}
+
+/*
+ * Processing of 3D modes declared via 3D_Struture_ALL and 3D_MASK
+ */
+void declare_short_3d(unsigned int struc_3d, unsigned int mask,
+                                               edid_info_t *edid)
+{
+       unsigned int i, j, modes;
+
+       /* Go through each 2D_VIC specified via 3D_MASK */
+       for (i = 0; i < 16; i++, mask = mask >> 1) {
+               /*
+                * Go through stereo variations specified via
+                * 3D_Structure_ALL
+                */
+               for (j = 0, modes = struc_3d; j < 16; j++, modes = modes >> 1) {
+                       if (modes & 0x01 && mask & 0x01)
+                               add_3d_mode_via_2d(i + 1, j, edid);
+               }
+       }
+}
+
+/*
+ * Processing of 3D modes declared via explicit list of 2D vics
+ */
+void declare_explicit_3d(unsigned char *e, unsigned int n, edid_info_t *edid)
+{
+       unsigned int i;
+
+       /* Go through the list of 2D_VIC_ORDER_X entries
+        * 0x08 typed entries are 2 bytes, others are 1 byte
+        */
+       for (i = 0; i < n; i += (e[i] & 0x0F) == 0x08 ? 2 : 1)
+               add_3d_mode_via_2d(((e[i] & 0xF0) >> 4) + 1, e[i] & 0x0F, edid);
+}
+
+/*
+ * decode_misc_modes()
+ */
+void decode_misc_modes(unsigned char *e, int n, edid_info_t *edid)
+{
+
+}
+
+#ifdef OTM_HDMI_FIXME
+/* TODO: Should be Revisted
+ * 3D parsing hangs system with edid09 of analyzer Bug206379 */
+/*
+ * decode_3D_modes()
+ */
+void decode_3D_modes(unsigned char *e, int n, int layout, edid_info_t *edid)
+{
+       unsigned int offset;
+
+       EDID_PRINT("- 3D modes supported:\n");
+
+       /* Declare mandatory modes */
+       declare_mandatory_3d(edid);
+
+       /* There are several ways of declaring 3D modes support */
+       switch (layout) {
+       case 0:          /* Mandatory modes only */
+               offset = 0;
+               break;
+
+       case 1:         /* Mandatory modes + variations described in
+                        * 3D_Structure_ALL */
+               /* supported by each of first 16 VICs */
+               offset = 2;
+               declare_short_3d(e[1] | (e[0] << 8), 0xFFFF, edid);
+               break;
+
+       case 2:          /* Mandatory modes + variations described in
+                         * 3D_Structure_ALL */
+               /* supported only by some of 16 first VICs
+                * [as told by 3D_MASK] */
+               offset = 4;
+               declare_short_3d(e[1] | (e[0] << 8), e[3] | (e[2] << 8), edid);
+               break;
+
+       default:                 /* Reserved for future use */
+               offset = 0;
+               break;
+       }
+
+       /* Declare 3D modes based on present 2D VIC entries */
+       declare_explicit_3d(e + offset, (n >= offset) ? n - offset : 0, edid);
+}
+#endif
+
+/*
+ * decode_vendor_data_block()
+ */
+void decode_vendor_data_block(unsigned char *e, int n, edid_info_t * edid)
+{
+       unsigned int pos;
+#ifdef OTM_HDMI_FIXME
+       unsigned int len_3d, len_hdmi;
+#endif
+
+       EDID_PRINT("[vendor specific data block.. length %d]\n", n);
+
+       /* Look for HDMI signature [0x030C00] */
+       if (n >= 3) {
+               if ((e[0] == 0x03) && (e[1] == 0x0C) && (e[2] == 0x00)) {
+                       edid->hdmi = true;
+                       EDID_PRINT("- HDMI signature found\n");
+               }
+       }
+       /* Parse Source Physical Address */
+       if (n >= 5)
+               edid->spa = (e[3] << 8) | e[4];
+       /* Look for more optional stuff */
+       if (n >= 6) {
+               /* Deep Color support */
+               edid->dc_48 = (e[5] & 0x40) != 0;
+               edid->dc_36 = (e[5] & 0x20) != 0;
+               edid->dc_30 = (e[5] & 0x10) != 0;
+               edid->dc_y444 = (e[5] & 0x08) != 0;
+
+               /* AI support */
+               edid->supports_ai = (e[5] & 0x80) != 0;
+       }
+       /* MAX TMDS clock */
+       if (n >= 7)
+               edid->max_tmds_clock = e[6] * 5;
+       /* Check for optional latency and 3D fields */
+       if ((n >= 8)) {
+               edid->latency_present = (e[7] & 0x80) != 0;
+               edid->latency_int_present = (e[7] & 0x40) != 0;
+               edid->hdmi_video_present = (e[7] & 0x20) != 0;
+       }
+       /* From now on keep explicit track of position we are reading */
+       pos = 8;
+
+       /* Get video latency [in ms] */
+       if (edid->latency_present) {
+               edid->latency_video = e[pos++];
+               edid->latency_audio = e[pos++];
+
+               /* Get interlaced video latency [in ms] */
+               if (edid->latency_int_present) {
+                       edid->latency_video_interlaced = e[pos++];
+                       edid->latency_audio_interlaced = e[pos++];
+               }
+       }
+
+#ifdef OTM_HDMI_FIXME
+       /* TODO: Should be Revisted
+        * 3D parsing hangs system with edid09 of analyzer Bug206379 */
+
+       /* 3D and misc modes information from HDMI 1.4 specification */
+       if (edid->hdmi_video_present) {
+               edid->enabled_3d = (e[pos++] & 0x80) != 0;
+
+               len_3d = (e[pos] & 0x1F);
+               len_hdmi = (e[pos++] & 0xE0) >> 5;
+
+               /* Assumption is that both misc and 3D modes can be
+                * present so deal with
+                * misc modes first
+                */
+               decode_misc_modes(e + pos, len_hdmi, edid);
+
+               /* Now deal with 3D stuff */
+               if (len_3d || edid->enabled_3d) {
+                       decode_3D_modes(e + pos + len_hdmi, len_3d,
+                                       (e[pos - 2] & 0x60) >> 5, edid);
+               }
+
+       }
+#endif
+
+}
+
+/*
+ * decode_extended_data_block()
+ */
+void decode_extended_data_block(unsigned char *e, int n, edid_info_t * edid)
+{
+       EDID_PRINT("[extended data block.. length %d]\n", n);
+
+       switch (*(e + 0)) {
+       case 0x00:               /* Video Capability Block */
+               EDID_PRINT("Video Capability Block\n");
+               edid->rgb_quant_selectable = *(e + 1) & 0x40;
+               edid->ycc_quant_selectable = *(e + 1) & 0x80;
+               break;
+       case 0x01:               /* Vendor Specific Video Data Block */
+               EDID_PRINT("Vendor Specific Video Data Block\n");
+               break;
+       case 0x05:               /* Colorimetry Block */
+               EDID_PRINT("Colorimetry Block\n");
+               if (n == 3) {
+                       edid->xvycc601 = (*(e + 1) & 0x01) != 0;
+                       edid->xvycc709 = (*(e + 1) & 0x02) != 0;
+               }
+               break;
+       case 0x11:               /* CEA Misc Audio Block */
+               EDID_PRINT("CEA Misc Audio Block\n");
+               break;
+       case 0x12:               /* Vendor specific audio data block */
+               EDID_PRINT("Vendor specific audio data Block\n");
+               break;
+       default:                 /* reserved blocks */
+               EDID_PRINT("Reserved Block\n");
+               break;
+       }
+
+}
+
+/*
+ * This is what short descriptor handler signature should look like
+ * NOTE: e is where payload starts, i.e. header byte is not included!!!
+ */
+typedef void (*short_block_decoder_t)(unsigned char *e, int n,
+                                       edid_info_t *edid);
+
+short_block_decoder_t short_block_decoders[] = {
+       /* Reserved */
+       NULL,
+       /* Audio data block decoder */
+       decode_audio_data_block,
+       /* Video data block decoder */
+       decode_video_data_block,
+       /* Vendor specific block decoder */
+       decode_vendor_data_block,
+       /* Speaker allocation block decoder */
+       decode_speaker_allocation_data_block,
+       /* VESA DTC data block decoder */
+       NULL,
+       /* Reserved */
+       NULL,
+       /* Extended tag handler */
+       decode_extended_data_block
+};
+
+/*
+ * decode_block_collection()
+ * See section 7.5 of CEA-861-C for details
+ */
+void decode_block_collection(extention_block_cea_t *eb, edid_info_t *edid)
+{
+       unsigned char *c = eb->data;
+       int block_type, payload_size;
+
+       /* All area before detailed descriptors should be filled
+        * TODO: Shall we change this to safer check?
+        */
+       while (c < ((unsigned char *)eb + eb->content_offset)) {
+               block_type = (*c & 0xE0) >> 5;
+               payload_size = *c & 0x1F;
+
+               /* Simple block types */
+               if ((block_type < 8) && (block_type >= 0)) {
+                       if (short_block_decoders[block_type]) {
+                               short_block_decoders[block_type] ((unsigned char
+                                                                  *)c + 1,
+                                                                 payload_size,
+                                                                 edid);
+                       } else {
+                               EDID_PRINT("[block 0x%x.. TBA]\n", block_type);
+                       }
+               }
+               /* Unknown */
+               else
+                       EDID_PRINT("[unknown block 0x%x]\n", (int)*c);
+
+               EDID_PRINT("\n");
+               c += (*c & 0x1F) + 1;
+       }
+}
+
+/*
+ * decode_standard_timings()
+ * Section 3.9.1 of EDID STD
+ */
+void decode_standard_timings(unsigned short st, edid_info_t *edid)
+{
+       struct {
+               int h;
+               int v;
+       } ar[] = { {
+       16, 10}, {
+       4, 3}, {
+       5, 4}, {
+       16, 9} };
+       otm_hdmi_timing_t pdt;
+       int r;
+
+       if (st != 0x0101) {
+               pdt.width = ((st & 0x00FF) + 31) * 8;
+               pdt.refresh = encode_refresh(((st & 0x3F00) >> 8) + 60);
+
+               r = ((st & 0xC000) >> 14);
+
+               /* Init flags with respect to aspect ratio */
+               pdt.mode_info_flags = (r == 3) ? PD_AR_16_BY_9 : 0;
+
+               /* TODO: Add proper logic for EDID earlier than 1.3
+                * This weird line below makes sure division by zero is avoided
+                */
+               pdt.height =
+                   pdt.width * ar[r].v / (ar[r].h ? ar[r].h : ar[r].v);
+
+               /* Indicate no stereo support */
+               pdt.stereo_type = OTM_HDMI_STEREO_NONE;
+
+               EDID_PRINT("[Standart timing]\n");
+               add_timings(edid, &pdt, 0);
+       }
+}
+
+/*
+ * decode_detailed_timings()
+ * Table 3.16 of EDID STD
+ */
+bool decode_detailed_timings(timing_descriptor_t *td,
+                                       otm_hdmi_timing_t *pdt)
+{
+       bool rc = true;
+
+       int pixel_clock = td->pixel_clock * 10;
+       int h_active = ((td->h_active_blanking_hb & 0xF0) << 4) | td->h_active;
+       int h_blanking =
+           ((td->h_active_blanking_hb & 0x0F) << 8) | td->h_blanking;
+       int v_active = ((td->v_active_blanking_hb & 0xF0) << 4) | td->v_active;
+       int v_blanking =
+           ((td->v_active_blanking_hb & 0x0F) << 8) | td->v_blanking;
+       int h_sync_off =
+           ((td->offset_pulse_width_hb & 0xC0) << 2) | td->h_sync_offset;
+       int h_sync_pw =
+           ((td->offset_pulse_width_hb & 0x30) << 4) | td->h_sync_pulse_width;
+
+       int v_sync_off = ((td->vs_offset_pulse_width & 0xF0) >> 4)
+           | (td->offset_pulse_width_hb & 0x0C);
+
+       int v_sync_pw = ((td->offset_pulse_width_hb & 0x03) << 4)
+           | (td->vs_offset_pulse_width & 0x0F);
+
+       int h_img_size = ((td->hv_image_size & 0xF0) << 4) | td->h_image_size;
+       int v_img_size = ((td->hv_image_size & 0x0F) << 8) | td->v_image_size;
+
+       EDID_PRINT("[detailed timing descriptor]\n");
+
+#ifndef PRINT_DETAILED_TIMINGS
+       EDID_PRINT(" - pixel_clock     : %d KHz\n", pixel_clock);
+       EDID_PRINT(" - horz_active     : %d pixels\n", h_active);
+       EDID_PRINT(" - horz_blanking   : %d pixels\n", h_blanking);
+       EDID_PRINT(" - vert_active     : %d lines\n", v_active);
+       EDID_PRINT(" - vert_blanking   : %d lines\n", v_blanking);
+       EDID_PRINT(" - horz_sync_off   : %d pixels\n", h_sync_off);
+       EDID_PRINT(" - horz_sync_pw    : %d pixels\n", h_sync_pw);
+       EDID_PRINT(" - vert_sync_off   : %d lines\n", v_sync_off);
+       EDID_PRINT(" - vert_sync_pw    : %d lines\n", v_sync_pw);
+       EDID_PRINT(" - image ratio     : %d : %d\n", h_img_size, v_img_size);
+#endif
+
+       pdt->width = h_active;
+       pdt->htotal = h_active + h_blanking;
+       pdt->hblank_start = h_active;
+       pdt->hblank_end = h_active + h_blanking;
+       pdt->hsync_start = h_active + h_sync_off;
+       pdt->hsync_end = h_active + h_sync_off + h_sync_pw;
+
+       pdt->height = v_active;
+       pdt->vtotal = v_active + v_blanking;
+       pdt->vblank_start = v_active;
+       pdt->vblank_end = v_active + v_blanking;
+       pdt->vsync_start = v_active + v_sync_off;
+       pdt->vsync_end = v_active + v_sync_off + v_sync_pw;
+
+       pdt->dclk = pixel_clock;
+
+       /* Make sure we are seeing valid mode */
+       VERIFY(pdt->htotal && pdt->vtotal && pdt->dclk, rc, false, exit);
+
+       pdt->refresh = (pdt->dclk * 1000) / (pdt->htotal * pdt->vtotal);
+
+       /* Convert refresh velue to enumeration entry */
+       pdt->refresh = encode_refresh(pdt->refresh);
+
+       /* Check if mode is interlaced */
+       pdt->mode_info_flags |= (td->flags & 0x80) ? PD_SCAN_INTERLACE : 0;
+
+       /* Determine picture aspect ratio */
+       pdt->mode_info_flags |=
+           (h_img_size / 4 == v_img_size / 3) ? 0 : PD_AR_16_BY_9;
+
+       /* Check for sync signal polarity */
+       if (td->flags & 0x18) {
+               pdt->mode_info_flags |= (td->flags & 0x02) ? PD_HSYNC_HIGH : 0;
+               pdt->mode_info_flags |= (td->flags & 0x04) ? PD_VSYNC_HIGH : 0;
+       }
+       /* Indicate no stereo support */
+       pdt->stereo_type = OTM_HDMI_STEREO_NONE;
+
+exit:
+       return rc;
+}
+
+/*
+ * decode_generic_descriptor()
+ * Table 3.19. Table 3.20 of EDID STD
+ */
+void decode_generic_descriptor(generic_descriptor_t *gd, edid_info_t *edid)
+{
+       int i;
+
+       /* Not a timing descriptor */
+       if ((gd->flag_required == 0) && (gd->flag_reserved == 0)
+           && (gd->flag == 0)) {
+               switch (gd->data_type_tag) {
+               case 0xFF:
+                       EDID_PRINT("[Monitor Serial Number ]\n");
+                       EDID_PRINT(" - %s\n", gd->payload);
+                       break;
+               case 0xFE:
+                       EDID_PRINT("[ASCII String          ]\n");
+                       EDID_PRINT(" - %s\n", gd->payload);
+                       break;
+               case 0xFD:
+                       EDID_PRINT("[Monitor Range Limits  ]\n");
+                       EDID_PRINT(" - ...\n");
+                       break;
+               case 0xFC:
+                       EDID_PRINT("[Monitor Name          ]\n");
+                       EDID_PRINT(" - %s\n", gd->payload);
+                       for (i = 0; i < 13; i++) {
+                               if (gd->payload[i] == '\n')
+                                       break;
+                               else
+                                       edid->product_name[i] = gd->payload[i];
+                       }
+                       break;
+               case 0xFB:
+                       EDID_PRINT("[Color Data            ]\n");
+                       break;
+               case 0xFA:
+                       EDID_PRINT("[More Standard Timings ]\n");
+                       for (i = 0; i < 12; i += 2) {
+                               /* TODO: Need more info on proper byte order */
+                               decode_standard_timings
+                                   ((gd->payload[i] << 8) | gd->payload[i + 1],
+                                    edid);
+                       }
+                       break;
+               case 0x10:
+                       EDID_PRINT("[Dummy                 ]\n");
+                       break;
+               default:
+                       EDID_PRINT("[Manufacturer/Undefined]\n");
+                       break;
+               }
+       }
+       /* Timing descriptor */
+       else {
+               otm_hdmi_timing_t pdt;
+               memset(&pdt, 0, sizeof(otm_hdmi_timing_t));
+               if (decode_detailed_timings((timing_descriptor_t *) gd, &pdt))
+                       add_timings(edid, &pdt, 0);
+       }
+}
+
+#define __BASIC_AUDIO_FS (OTM_HDMI_AUDIO_FS_32_KHZ | \
+                       OTM_HDMI_AUDIO_FS_44_1_KHZ | \
+                       OTM_HDMI_AUDIO_FS_48_KHZ)
+
+/*
+ * __find_and_declare_basic_audio_support()
+ */
+static otm_hdmi_ret_t __find_and_declare_basic_audio_support(edid_info_t *edid)
+{
+       otm_hdmi_audio_cap_t *caps = edid->audio_caps;
+       unsigned int i = 0;
+
+       otm_hdmi_audio_cap_t cap = {
+               .format = OTM_HDMI_AUDIO_FORMAT_PCM,
+               .max_channels = 2,
+               .fs = __BASIC_AUDIO_FS,
+               .ss_bitrate = OTM_HDMI_AUDIO_SS_16,
+       };
+
+       /* Try to find basic audio functionality among declared capabilities */
+       for (i = 0; i < edid->num_caps; i++) {
+               if ((caps[i].format == cap.format)
+                   && (caps[i].max_channels >= cap.max_channels)
+                   && (caps[i].ss_bitrate & cap.ss_bitrate)
+                   && ((caps[i].fs & cap.fs) == cap.fs)) {
+                       goto exit;
+               }
+       }
+
+       /* Add RLRF pair to the speaker allocation map */
+       edid->speaker_map |= 0x01;
+
+       /* Add basic audio capability to the list of capabilities */
+       memcpy(&caps[edid->num_caps++], &cap, sizeof(cap));
+
+exit:
+       return OTM_HDMI_SUCCESS;
+}
+
+/*
+ * decode_extention_block_cea()
+ * Refer to section A.2.13 of CEA-861-C document for additional details
+ */
+void decode_extention_block_cea(extention_block_cea_t *eb, edid_info_t *edid)
+{
+       int i;
+       generic_descriptor_t gd;
+
+       /* Check YCbCr444 and YCbCr422 support */
+       if (eb->revision >= 2) {
+               edid->ycbcr444 = (eb->flags & 0x20) ? true : false;
+               edid->ycbcr422 = (eb->flags & 0x10) ? true : false;
+       }
+       /*
+        * Short descriptors section exists when:
+        * - offset is not 4
+        * - CEA extension version is 3
+        */
+       if ((eb->content_offset != 4) && (eb->revision >= 3))
+               decode_block_collection(eb, edid);
+       /*
+        * Detailed timing descriptors:
+        * - do not exist when offset is zero
+        * - may still not exist even when offset is non-zero; in this case
+        *   location where they would exist is padded so make sure
+        *   appropriate decoding routine can handle that padding correctly
+        */
+#define __DSCR_SIZE 18
+       if (eb->content_offset != 0) {
+               for (i = 0; i < (128 - eb->content_offset) / __DSCR_SIZE; i++) {
+                       /*
+                        * Instead of using a casted pointer to descriptor,
+                        * we explicitely copy memory content temporary
+                        * placeholder. This way we are avoiding possible
+                        * integer addressing problems
+                        */
+                       memcpy(&gd,
+                              (char *)eb + eb->content_offset +
+                              __DSCR_SIZE * i, __DSCR_SIZE);
+                       decode_generic_descriptor(&gd, edid);
+               }
+       }
+#undef __DSCR_SIZE
+
+       /* Check for basic audio support and add it to caps list if necessary */
+       if ((eb->revision >= 2) && (eb->flags & 0x40))
+               __find_and_declare_basic_audio_support(edid);
+}
+
+/*
+ * fetch_block_map()
+ */
+otm_hdmi_ret_t fetch_block_map(edid_block_map_t *ebm, unsigned char *data)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       read_context_t read_context = { data, 0 };
+       read_context_t *rctx = &read_context;
+
+       VERIFY(ebm != NULL, rc, OTM_HDMI_ERR_INTERNAL, exit);
+       VERIFY(data != NULL, rc, OTM_HDMI_ERR_INTERNAL, exit);
+
+       /* Fill tag, map and checksum fields */
+       fetch_next_field(&ebm->tag, rctx, 1);
+       fetch_next_field(&ebm->map, rctx, BLOCK_MAP_SIZE);
+       fetch_next_field(&ebm->checksum, rctx, 2);
+
+exit:
+       return rc;
+}
+
+/*
+ * block_decode()
+ */
+otm_hdmi_ret_t block_decode(edid_info_t *edid_info, unsigned int type,
+                                       unsigned char *buffer)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       extention_block_cea_t eb;
+
+       EDID_PRINT("Decoding extension 0x%x\n", type);
+
+       switch (type) {
+       case 0x02:
+               VERIFY(buffer[0] == 0x02, rc, OTM_HDMI_ERR_FAILED, exit);
+               memset(&eb, 0, sizeof(extention_block_cea_t));
+               fetch_extension_block_cea(&eb, buffer);
+               decode_extention_block_cea(&eb, edid_info);
+               break;
+
+       default:
+               EDID_PRINT("Extension 0x%x is not supported; Bypassing\n",
+                          type);
+               break;
+       }
+
+exit:
+       return rc;
+}
+
+int edid_parse_pd_timing_from_cea_block(edid_info_t *edid_info,
+                                       unsigned char *buffer,
+                                       otm_hdmi_timing_t *pdts)
+{
+       extention_block_cea_t eb;
+       int i = 0;
+
+       if (buffer[0x0] == 0x2) {
+               memset(&eb, 0, sizeof(extention_block_cea_t));
+               edid_info->num_timings = 0;
+               fetch_extension_block_cea(&eb, buffer);
+               decode_extention_block_cea(&eb, edid_info);
+
+               for (i = 0; i < edid_info->num_timings; i++) {
+                       memcpy((unsigned char *)&pdts[i],
+                                    (unsigned char *)&edid_info->timings[i],
+                                    sizeof(otm_hdmi_timing_t));
+               }
+               return edid_info->num_timings;
+       }
+       return 0;
+}
+
+
+/*
+ * edid_parse()
+ */
+otm_hdmi_ret_t edid_parse(edid_info_t *edid_info,
+                       i2c_read_t data_read, void *cd,
+                       bool hex_dump)
+{
+       unsigned char buffer[SEGMENT_SIZE];
+       edid_block_zero_t ebz;
+       edid_block_map_t ebm;
+       extention_block_cea_t eb;
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       int i, sp, offset;
+
+       /* Read block zero */
+       rc = data_read(cd, 0, 0, buffer, SEGMENT_SIZE);
+       VERIFY_QUICK(rc == OTM_HDMI_SUCCESS, exit);
+       print_raw_block(buffer, SEGMENT_SIZE, (bool) hex_dump);
+       VERIFY(checksum_valid(buffer, SEGMENT_SIZE), rc,
+                               OTM_HDMI_ERR_FAILED, exit);
+
+       /* Process block zero */
+       memset(&ebz, 0, sizeof(edid_block_zero_t));
+       fetch_block_zero(&ebz, buffer);
+
+       VERIFY(ebz.signature == EDID_SIGNATURE, rc, OTM_HDMI_ERR_FAILED, exit);
+
+       /* Decode general stuff */
+       edid_info->manufacturer_id = ebz.manufacturer_id;
+       edid_info->product_code = ebz.product_code;
+       edid_info->product_sn = ebz.serial_number;
+       edid_info->product_year = ebz.manufacture_year + 1990;
+       edid_info->product_week = ebz.manufacture_week;
+       edid_info->max_horz_image_size = ebz.max_horz_image_size;
+       edid_info->max_vert_image_size = ebz.max_vert_image_size;
+       edid_info->native_idx = -1;
+
+       /* Decode timings */
+       decode_generic_descriptor((generic_descriptor_t *) &ebz.td_1,
+                                 edid_info);
+       decode_generic_descriptor((generic_descriptor_t *) &ebz.td_2,
+                                 edid_info);
+       decode_generic_descriptor((generic_descriptor_t *) &ebz.md_1,
+                                 edid_info);
+       decode_generic_descriptor((generic_descriptor_t *) &ebz.md_2,
+                                 edid_info);
+
+       for (i = 0; i < EDID_STD_TIMINGS_NUM; i++)
+               decode_standard_timings(ebz.std_timings[i], edid_info);
+
+       /* If there are no extentions - we are done */
+       VERIFY(ebz.num_extentions != 0, rc, OTM_HDMI_SUCCESS, exit);
+
+       /* Read next block */
+       rc = data_read(cd, 0, SEGMENT_SIZE, buffer, SEGMENT_SIZE);
+       VERIFY_QUICK(rc == OTM_HDMI_SUCCESS, exit);
+       print_raw_block(buffer, SEGMENT_SIZE, (bool) hex_dump);
+       VERIFY(checksum_valid(buffer, SEGMENT_SIZE), rc,
+                               OTM_HDMI_ERR_FAILED, exit);
+
+       /* There is only 1 extention; Assume its CEA Extension [tag = 0x02] */
+       if (ebz.num_extentions == 1) {
+               /* Process extention block */
+               memset(&eb, 0, sizeof(extention_block_cea_t));
+               fetch_extension_block_cea(&eb, buffer);
+               VERIFY(eb.tag == 0x02, rc, OTM_HDMI_SUCCESS, exit);
+               decode_extention_block_cea(&eb, edid_info);
+       }
+       /* There is a block map and more extentions */
+       else {
+               /* Process block map */
+               memset(&ebm, 0, sizeof(edid_block_map_t));
+               fetch_block_map(&ebm, buffer);
+
+               /* Verify we are indeed dealing with map block */
+               VERIFY(ebm.tag == 0xF0, rc, OTM_HDMI_ERR_FAILED, exit);
+
+               /* Deal with each block in the map */
+               for (i = 0; (i < BLOCK_MAP_SIZE) && ebm.map[i]; i++) {
+                       /* Compute extension block location */
+                       sp = (i + 2) / 2;
+                       offset = (i % 2) ? SEGMENT_SIZE : 0;
+
+                       /* Read extension block */
+                       rc = data_read(cd, sp, offset, buffer, SEGMENT_SIZE);
+                       VERIFY_QUICK(rc == OTM_HDMI_SUCCESS, exit);
+                       print_raw_block(buffer, SEGMENT_SIZE, (bool) hex_dump);
+                       VERIFY(checksum_valid(buffer, SEGMENT_SIZE), rc,
+                              OTM_HDMI_ERR_FAILED, exit);
+
+                       /* Decode extension block */
+                       rc = block_decode(edid_info, ebm.map[i], buffer);
+                       VERIFY_QUICK(rc == OTM_HDMI_SUCCESS, exit);
+               }
+
+               goto exit;
+       }
+
+exit:
+       return rc;
+}
+
+/*
+ * TODO LIST (in addition to small todos in the code)
+ *
+ * 1. Currently we parse ALL timings, but return only those supported by CE 3100
+ *    Shall we change it so it behaves like true parser and returns ALL timings?
+ */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/common/edid.h b/drivers/staging/mrst/drv/otm_hdmi/pil/common/edid.h
new file mode 100644 (file)
index 0000000..45e671a
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef _EDID_H
+#define _EDID_H
+
+
+#include <linux/types.h>
+
+#include "otm_hdmi.h"
+
+#define MAX_TIMINGS 100
+#define MAX_CAPS 30
+#define SEGMENT_SIZE 128
+#define MAX_EDID_BLOCKS 5
+
+/**
+ * Different types representing pointers to a function
+ */
+typedef otm_hdmi_ret_t (*i2c_read_t)(void *client_data, unsigned int sp,
+                                    unsigned int offset, void *buffer,
+                                    unsigned int size);
+
+typedef int (*printf_t) (const char *fmt, ...);
+
+/**
+ * Structure with parsed EDID information returned to end user
+ */
+typedef struct {
+       bool hdmi;      /* HDMI or DVI device */
+       unsigned int num_timings;       /* Number of supported timings */
+       otm_hdmi_timing_t timings[MAX_TIMINGS]; /* Supported timings */
+       unsigned int order[MAX_TIMINGS];        /* VIC order of descovery */
+       unsigned int num_caps;  /* Number of supported audiocaps */
+       otm_hdmi_audio_cap_t audio_caps[MAX_CAPS];      /* Supported audio caps
+                                                       */
+       unsigned int speaker_map;       /* Speaker layout */
+       unsigned short manufacturer_id; /* Manufacturer ID */
+       unsigned short product_code;    /* Product code */
+       unsigned int product_sn;        /* Serial number */
+       unsigned int product_year;      /* Year of product manufacture */
+       unsigned int product_week;      /* Week of product manufacture */
+       unsigned char product_name[14]; /* Product name */
+       bool ycbcr444;  /* YCbCr444 support */
+       bool ycbcr422;  /* YCbCr422 support */
+       unsigned int spa;       /* CEC source physical address */
+       bool dc_30;     /* 30 bit Deep Color support */
+       bool dc_36;     /* 36 bit Deep Color support */
+       bool dc_48;     /* 48 bit Deep Color support */
+       bool dc_y444;   /* YCbCr444 support with DC */
+       bool xvycc601;  /* xvYCC BT601 Colorimetry */
+       bool xvycc709;  /* xvYCC BT709 Colorimetry */
+       bool supports_ai;       /* Aux audio info support */
+       unsigned int max_tmds_clock;
+       bool latency_present;
+       bool latency_int_present;
+       bool hdmi_video_present;
+       int latency_video;
+       int latency_audio;
+       int latency_video_interlaced;
+       int latency_audio_interlaced;
+       bool enabled_3d;
+       bool supports_60Hz;
+       bool supports_50Hz;
+       unsigned char max_horz_image_size;
+       unsigned char max_vert_image_size;
+       int native_idx;
+       bool rgb_quant_selectable;      /*rgb quant mode selectable */
+       bool ycc_quant_selectable;      /*ycc quant mode selectable */
+
+       const otm_hdmi_timing_t **ref_timings;  /* INPUT: reference timings
+                                                  table */
+       unsigned int num_ref_timings;   /* INPUT: size of ref timings table */
+} edid_info_t;
+
+otm_hdmi_ret_t edid_parse(edid_info_t *edid_info, i2c_read_t data_read,
+                         void *cd, bool hex_dump);
+
+void print_pd_timing(const otm_hdmi_timing_t *pdt, unsigned int order,
+                    printf_t print);
+void print_audio_capability(otm_hdmi_audio_cap_t *adb, printf_t print);
+void print_speaker_layout(unsigned int layout, printf_t print);
+void print_raw_block(unsigned char *buffer, int size, bool print);
+
+int find_timing(const otm_hdmi_timing_t *set, int size,
+               const otm_hdmi_timing_t *e);
+
+int edid_parse_pd_timing_from_cea_block(edid_info_t *edid_info,
+                                       unsigned char *buffer,
+                                       otm_hdmi_timing_t *pdts);
+#endif /* _EDID_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/common/edid_internal.h b/drivers/staging/mrst/drv/otm_hdmi/pil/common/edid_internal.h
new file mode 100644 (file)
index 0000000..ac30733
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef _EDID_INTERNAL_H
+#define _EDID_INTERNAL_H
+
+#include "edid.h"
+
+#define EDID_STD_TIMINGS_NUM 8
+#define BLOCK_MAP_SIZE 126
+
+/*
+ * Structure representing timing descriptor in EDID native format
+ * See Table 3.16 of EDID STD and Table 50 of CEA-861-C documents for details
+ * Order of fields MUST match documentation
+ */
+typedef struct {
+       unsigned short pixel_clock;
+       unsigned char h_active;
+       unsigned char h_blanking;
+       unsigned char h_active_blanking_hb;
+       unsigned char v_active;
+       unsigned char v_blanking;
+       unsigned char v_active_blanking_hb;
+       unsigned char h_sync_offset;
+       unsigned char h_sync_pulse_width;
+       unsigned char vs_offset_pulse_width;
+       unsigned char offset_pulse_width_hb;
+       unsigned char h_image_size;
+       unsigned char v_image_size;
+       unsigned char hv_image_size;
+       unsigned char h_border;
+       unsigned char v_border;
+       unsigned char flags;
+} timing_descriptor_t;
+
+/*
+ * Structure representing any 18 bytes descriptor
+ * See Table 3.19 and 3.20 of EDID STD for details
+ * Order of fields MUST match documentation
+ */
+typedef struct {
+       unsigned short flag_required;
+       unsigned char flag_reserved;
+       unsigned char data_type_tag;
+       unsigned char flag;
+       unsigned char payload[13];
+} generic_descriptor_t;
+
+/*
+ * Structure representing EDID CEA extention block
+ * See Table 56, Table 26 and section A.2.13 of CEA-861-C for details
+ */
+typedef struct {
+       unsigned char tag;
+       unsigned char revision;
+       unsigned char content_offset;
+       unsigned char flags;
+       unsigned char data[124];
+} extention_block_cea_t;
+
+/*
+ * EDID Block 0
+ */
+typedef struct {
+       unsigned long long signature;
+       unsigned short manufacturer_id;
+       unsigned short product_code;
+       unsigned int serial_number;
+       unsigned char manufacture_week;
+       unsigned char manufacture_year;
+       unsigned char version;
+       unsigned char revision;
+       unsigned char video_input_definition;
+       unsigned char max_horz_image_size;
+       unsigned char max_vert_image_size;
+       unsigned char gamma;
+       unsigned char feature_support;
+       unsigned char rg_lowbits;
+       unsigned char bw_lowbits;
+       unsigned char red_x;
+       unsigned char red_y;
+       unsigned char green_x;
+       unsigned char green_y;
+       unsigned char blue_x;
+       unsigned char blue_y;
+       unsigned char white_x;
+       unsigned char white_y;
+       unsigned char est_timing_1;
+       unsigned char est_timing_2;
+       unsigned char est_timing_3;
+       unsigned short std_timings[EDID_STD_TIMINGS_NUM];
+       unsigned char td_1[sizeof(generic_descriptor_t)];
+       unsigned char td_2[sizeof(generic_descriptor_t)];
+       unsigned char md_1[sizeof(generic_descriptor_t)];
+       unsigned char md_2[sizeof(generic_descriptor_t)];
+       unsigned char num_extentions;
+} edid_block_zero_t;
+
+/*
+ * EDID block map
+ */
+typedef struct {
+       unsigned char tag;
+       unsigned char map[BLOCK_MAP_SIZE];
+       unsigned char checksum;
+} edid_block_map_t;
+
+/*
+ * Detailed printing routines prototypes
+ */
+void print_monitor_descriptor_undecoded(generic_descriptor_t *md,
+                                       printf_t print);
+
+void print_timing_descriptor_undecoded(timing_descriptor_t *td,
+                                      printf_t print);
+
+void print_block_zero_undecoded(edid_block_zero_t *ebz, printf_t print);
+
+#endif /* _EDID_INTERNAL_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/common/edid_print.c b/drivers/staging/mrst/drv/otm_hdmi/pil/common/edid_print.c
new file mode 100644 (file)
index 0000000..523cf1f
--- /dev/null
@@ -0,0 +1,358 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#include <linux/kernel.h>
+#include "edid_internal.h"
+
+/* __fake_printf */
+static int __fake_printf(const char *fmt, ...)
+{
+       return 0;
+}
+
+/* Convert the refresh rate enum to a string for printing */
+static char *_refresh_string(otm_hdmi_refresh_t r)
+{
+       char *ret;
+
+       switch (r) {
+       case OTM_HDMI_REFRESH_23_98:
+               ret = "23.98";
+               break;
+       case OTM_HDMI_REFRESH_24:
+               ret = "24";
+               break;
+       case OTM_HDMI_REFRESH_25:
+               ret = "25";
+               break;
+       case OTM_HDMI_REFRESH_29_97:
+               ret = "29.97";
+               break;
+       case OTM_HDMI_REFRESH_30:
+               ret = "30";
+               break;
+       case OTM_HDMI_REFRESH_50:
+               ret = "50";
+               break;
+       case OTM_HDMI_REFRESH_47_96:
+               ret = "47.96";
+               break;
+       case OTM_HDMI_REFRESH_48:
+               ret = "48";
+               break;
+       case OTM_HDMI_REFRESH_59_94:
+               ret = "59.94";
+               break;
+       case OTM_HDMI_REFRESH_60:
+               ret = "60";
+               break;
+       case OTM_HDMI_REFRESH_NONE:
+               ret = "0";
+               break;
+       default:
+               ret = "<Unknown refresh rate>";
+               break;
+       };
+
+       return ret;
+}
+
+/* Convert stereo enum to a string for printing */
+static char *_stereo_string(otm_hdmi_stereo_t stereo_type)
+{
+       char *ret;
+
+       switch (stereo_type) {
+       case OTM_HDMI_STEREO_NONE:
+               ret = "Stereo None";
+               break;
+       case OTM_HDMI_STEREO_FRAME_PACKING_2:
+               ret = "Stereo Frame Packing 2";
+               break;
+       case OTM_HDMI_STEREO_FRAME_PACKING:
+               ret = "Stereo Frame Packing";
+               break;
+       case OTM_HDMI_STEREO_SIDE_BY_SIDE_HALF_2:
+               ret = "Stereo Side by Side Half 2";
+               break;
+       case OTM_HDMI_STEREO_TOP_BOTTOM_HALF_2:
+               ret = "Stereo Top Bottom Half 2";
+               break;
+       case OTM_HDMI_STEREO_FRAME_SEQUENTIAL:
+               ret = "Stereo Frame Sequential";
+               break;
+       default:
+               ret = "<Unknown Stereo type>";
+               break;
+       };
+
+       return ret;
+}
+
+/* print_pd_timing */
+void print_pd_timing(const otm_hdmi_timing_t *t,
+                    unsigned int order, printf_t print)
+{
+       printf_t p = print ? print : __fake_printf;
+
+       p(" - %dx%d @ %s", t->width, t->height, _refresh_string(t->refresh));
+       p("%s", (t->mode_info_flags & PD_SCAN_INTERLACE) ? "i" : "p");
+       p(" [%s]", (t->mode_info_flags & PD_AR_16_BY_9) ? "16:9" : "4:3");
+       p(" [%d]", order);
+       p(" [%s]\n", _stereo_string(t->stereo_type));
+
+#ifdef PRINT_DETAILED_TIMINGS
+       p(" - htotal      : %d\n", t->htotal);
+       p(" - hblank_start: %d\n", t->hblank_start);
+       p(" - hblank_end  : %d\n", t->hblank_end);
+       p(" - hsync_start : %d\n", t->hsync_start);
+       p(" - hsync_end   : %d\n", t->hsync_end);
+       p(" - vtotal      : %d\n", t->vtotal);
+       p(" - vblank_start: %d\n", t->vblank_start);
+       p(" - vblank_end  : %d\n", t->vblank_end);
+       p(" - vsync_start : %d\n", t->vsync_start);
+       p(" - vsync_end   : %d\n", t->vsync_end);
+       p(" - clock       : %dMhz\n", (int)(t->dclk / 1000));
+#endif
+}
+
+/* Convert audio format enum to a string for printing */
+static char *_audio_format(otm_hdmi_audio_fmt_t fmt)
+{
+       char *s;
+
+       switch (fmt) {
+       case OTM_HDMI_AUDIO_FORMAT_PCM:
+               s = "PCM";
+               break;
+       case OTM_HDMI_AUDIO_FORMAT_AC3:
+               s = "AC3";
+               break;
+       case OTM_HDMI_AUDIO_FORMAT_MPEG1:
+               s = "MPEG1";
+               break;
+       case OTM_HDMI_AUDIO_FORMAT_MP3:
+               s = "MP3";
+               break;
+       case OTM_HDMI_AUDIO_FORMAT_MPEG2:
+               s = "MPEG2";
+               break;
+       case OTM_HDMI_AUDIO_FORMAT_AAC:
+               s = "AAC";
+               break;
+       case OTM_HDMI_AUDIO_FORMAT_DTS:
+               s = "DTS";
+               break;
+       case OTM_HDMI_AUDIO_FORMAT_ATRAC:
+               s = "ATRAC";
+               break;
+       case OTM_HDMI_AUDIO_FORMAT_OBA:
+               s = "One Bit Audio";
+               break;
+       case OTM_HDMI_AUDIO_FORMAT_DDP:
+               s = "Dolby Digital +";
+               break;
+       case OTM_HDMI_AUDIO_FORMAT_DTSHD:
+               s = "DTSHD";
+               break;
+       case OTM_HDMI_AUDIO_FORMAT_MLP:
+               s = "MLP";
+               break;
+       case OTM_HDMI_AUDIO_FORMAT_DST:
+               s = "DST";
+               break;
+       case OTM_HDMI_AUDIO_FORMAT_WMA_PRO:
+               s = "WMA Pro";
+               break;
+       default:
+               s = "< unknown format >";
+               break;
+       };
+
+       return s;
+}
+
+/* Convert sampling rate enum to a string for printing */
+static char *_sampling_rate(otm_hdmi_audio_fs_t fs)
+{
+       char *s;
+
+       switch (fs) {
+       case OTM_HDMI_AUDIO_FS_32_KHZ:
+               s = "32";
+               break;
+       case OTM_HDMI_AUDIO_FS_44_1_KHZ:
+               s = "44.1";
+               break;
+       case OTM_HDMI_AUDIO_FS_48_KHZ:
+               s = "48";
+               break;
+       case OTM_HDMI_AUDIO_FS_88_2_KHZ:
+               s = "88.2";
+               break;
+       case OTM_HDMI_AUDIO_FS_96_KHZ:
+               s = "96";
+               break;
+       case OTM_HDMI_AUDIO_FS_176_4_KHZ:
+               s = "176.4";
+               break;
+       case OTM_HDMI_AUDIO_FS_192_KHZ:
+               s = "192";
+               break;
+
+       default:
+               s = "< unknown sampling rate >";
+               break;
+       }
+
+       return s;
+}
+
+/* print_audio_capability() */
+void print_audio_capability(otm_hdmi_audio_cap_t *cap, printf_t print)
+{
+       printf_t p = print ? print : __fake_printf;
+       int i;
+
+       p(" - Format: %s; Max channels: %d; Sampling rates, KHz:",
+         _audio_format(cap->format), cap->max_channels);
+
+       for (i = 0; i < 7; i++)
+               p(" %s", (cap->fs & (1 << i)) ? _sampling_rate(1 << i) : "");
+       p("\n");
+}
+
+/* Convert a speaker map enum to a string for printing */
+static char *_speaker_map(otm_hdmi_audio_speaker_map_t map)
+{
+       char *s;
+
+       switch (map) {
+       case OTM_HDMI_AUDIO_SPEAKER_MAP_FLFR:
+               s = "FL/FR";
+               break;
+       case OTM_HDMI_AUDIO_SPEAKER_MAP_LFE:
+               s = "LFE";
+               break;
+       case OTM_HDMI_AUDIO_SPEAKER_MAP_FC:
+               s = "FC";
+               break;
+       case OTM_HDMI_AUDIO_SPEAKER_MAP_RLRR:
+               s = "RL/RR";
+               break;
+       case OTM_HDMI_AUDIO_SPEAKER_MAP_RC:
+               s = "RC";
+               break;
+       case OTM_HDMI_AUDIO_SPEAKER_MAP_FLCFRC:
+               s = "FLC/FRC";
+               break;
+       case OTM_HDMI_AUDIO_SPEAKER_MAP_RLCRRC:
+               s = "RLC/RRC";
+               break;
+       case OTM_HDMI_AUDIO_SPEAKER_MAP_FLWFRW:
+               s = "FLW/FRW";
+               break;
+       case OTM_HDMI_AUDIO_SPEAKER_MAP_FLHFRH:
+               s = "FLH/FRH";
+               break;
+       case OTM_HDMI_AUDIO_SPEAKER_MAP_TC:
+               s = "TC";
+               break;
+       case OTM_HDMI_AUDIO_SPEAKER_MAP_FCH:
+               s = "FCH";
+               break;
+
+       default:
+               s = "< unknown allocation >\n";
+               break;
+       }
+
+       return s;
+}
+
+/* print_speaker_layout() */
+void print_speaker_layout(unsigned int layout, printf_t print)
+{
+       printf_t p = print ? print : __fake_printf;
+       int i;
+
+       p(" - Speaker layout map:");
+       for (i = 0; i < 11; i++)
+               p(" %s", (layout & (1 << i)) ? _speaker_map(1 << i) : "");
+       p("\n");
+}
+
+/* print_raw_block() */
+void print_raw_block(unsigned char *buffer, int size, bool print)
+{
+       int i;
+
+       if (!print)
+               return;
+
+       for (i = 0; i < size; i++) {
+               pr_debug("%s", (i % 0x10) ? "" : "\n");
+               pr_debug("%02X ", buffer[i]);
+       }
+       pr_debug("\n");
+}
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/common/hdcp.c b/drivers/staging/mrst/drv/otm_hdmi/pil/common/hdcp.c
new file mode 100644 (file)
index 0000000..eae4761
--- /dev/null
@@ -0,0 +1,859 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/types.h>
+#include "hdcp_rx_defs.h"
+#include "otm_hdmi.h"
+#include "otm_hdmi_types.h"
+#include "ipil_hdcp_api.h"
+
+#define OTM_HDCP_DEBUG_MODULE
+
+#ifdef OTM_HDCP_DEBUG_MODULE
+bool module_disable_hdcp = false;
+EXPORT_SYMBOL_GPL(module_disable_hdcp);
+bool module_force_ri_mismatch = false;
+EXPORT_SYMBOL_GPL(module_force_ri_mismatch);
+#endif
+
+enum {
+       HDCP_ENABLE = 1,
+       HDCP_RESET,
+       HDCP_RI_CHECK,
+       HDCP_REPEATER_CHECK,
+       HDCP_REPEATER_WDT_EXPIRED,
+       HDCP_SET_POWER_SAVE_STATUS,
+       HDCP_SET_HPD_STATUS,
+       HDCP_SET_DPMS_STATUS
+} hdcp_task_msg_en;
+
+struct hdcp_wq_struct_t {
+       struct delayed_work dwork;/* TODO: Needs Cosai Struct */
+       int msg;
+       void *msg_data;
+};
+
+/* = = = = = = = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = */
+/*!  \brief Our local context.
+ */
+struct hdcp_context_t {
+       int             can_authenticate;
+                       /*!< indicates HDCP Authentication currently allowed
+                        */
+       bool    is_required;
+       bool    is_enabled;
+       bool    suspend;
+       bool    hpd;
+       bool    display_power_on;
+       bool    auto_retry;
+       bool    wdt_expired;
+
+       unsigned int    current_srm_ver;
+                       /*!< currently used SRM version (if vrl is not null)
+                        */
+       uint64_t        *vrl;
+                       /*!< pointer to our VRL, formatted as array of KSVs
+                        * as hdcp__u64_t's
+                        */
+       unsigned int    vrl_count;
+                       /*!< total number of KSVs in our VRL */
+       int (*ddc_read_write)(bool, uint8_t, uint8_t, uint8_t *, int);
+                       /*!< Pointer to callback function for DDC Read Write */
+       struct workqueue_struct *hdcp_wq;
+};
+
+/* Global instance of local context */
+static struct hdcp_context_t *hdcp_context;
+
+/* HDCP Main Event Handler */
+static void hdcp_task_event_handler(struct work_struct *work);
+
+static bool wq_send_message_delayed(int msg,
+                                       void *msg_data,
+                                       unsigned long delay)
+{
+       struct hdcp_wq_struct_t *hwq = NULL;
+       hwq = kmalloc(sizeof(struct hdcp_wq_struct_t), GFP_KERNEL);
+       if (hwq == NULL)
+               return false;
+       hwq->msg = msg;
+       hwq->msg_data = msg_data;
+       /* TODO: Needs Cosai Calls */
+       INIT_DELAYED_WORK(&hwq->dwork, hdcp_task_event_handler);
+       /* TODO: Needs Cosai Calls */
+       if (queue_delayed_work(hdcp_context->hdcp_wq, &hwq->dwork,
+               (unsigned long)(msecs_to_jiffies(delay))) != 0)
+               return true;
+       else
+               pr_debug("hdcp: failed to add messge to delayed wq\n");
+       return false;
+}
+
+static bool wq_send_message(int msg, void *msg_data)
+{
+       return wq_send_message_delayed(msg, msg_data, 0);
+}
+
+static bool hdcp_enable_condition_ready(void)
+{
+       if (hdcp_context != NULL &&
+           hdcp_context->can_authenticate == true &&
+           hdcp_context->is_required == true &&
+           hdcp_context->suspend == false &&
+           hdcp_context->hpd == true &&
+           hdcp_context->display_power_on == true)
+               return true;
+
+       return false;
+}
+
+static int hdcp_ddc_read(uint8_t offset, uint8_t *buffer, int size)
+{
+       if (hdcp_enable_condition_ready() == true)
+               return hdcp_context->ddc_read_write(true,
+                       HDCP_PRIMARY_I2C_ADDR, offset, buffer, size);
+       return false;
+}
+
+static int hdcp_ddc_write(uint8_t offset, uint8_t *buffer, int size)
+{
+       if (hdcp_enable_condition_ready() == true)
+               return hdcp_context->ddc_read_write(false,
+                       HDCP_PRIMARY_I2C_ADDR, offset, buffer, size);
+       return false;
+}
+
+static uint64_t hdcp_ksv_64val_conv(uint8_t *ksv, uint32_t size)
+{
+       int i = 0;
+       uint64_t ksv64 = 0;
+       if (ksv != NULL && size == HDCP_KSV_SIZE) {
+               for (i = 0; i < 5; i++)
+                       ksv64 |= (ksv[i] << (i*8));
+       }
+       return ksv64;
+}
+
+static bool hdcp_validate_ksv(uint8_t *ksv, uint32_t size)
+{
+       int i = 0, count = 0;
+       uint8_t temp = 0;
+       uint64_t ksv64 = hdcp_ksv_64val_conv(ksv, size);
+       bool ret = false;
+       if (ksv != NULL  && size == HDCP_KSV_SIZE) {
+               count = 0;
+               for (i = 0; i < 5; i++) {
+                       temp = ksv[i];
+                       while (temp) {
+                               temp &= (temp-1);
+                               count++;
+                       }
+               }
+               if (count == HDCP_KSV_HAMMING_WT)
+                       ret = true;
+       }
+       if (ret) {
+               /* SRM Check ? */
+               if (hdcp_context->vrl != NULL) {
+                       const uint64_t *vrl = hdcp_context->vrl;
+                       for (i = 0; i < hdcp_context->vrl_count; i++, vrl++) {
+                               if (ksv64 == *vrl)
+                                       return true;
+                       }
+               }
+       }
+       return ret;
+}
+
+static bool hdcp_get_aksv(uint8_t *aksv, uint32_t size)
+{
+       bool ret = false;
+       if (ipil_hdcp_get_aksv(aksv, HDCP_KSV_SIZE) == true) {
+               if (hdcp_validate_ksv(aksv, size) == true)
+                       ret = true;
+       }
+       return ret;
+}
+
+static bool hdcp_read_bksv(uint8_t *bksv, uint32_t size)
+{
+       bool ret = false;
+       if (bksv != NULL  && size == HDCP_KSV_SIZE) {
+               if (hdcp_ddc_read(HDCP_RX_BKSV_ADDR,
+                               bksv, HDCP_KSV_SIZE) == true) {
+                       if (hdcp_validate_ksv(bksv, size) == true)
+                               ret = true;
+               }
+       }
+       return ret;
+}
+
+static bool hdcp_read_bcaps(uint8_t *bcaps)
+{
+       bool ret = false;
+       if (bcaps != NULL) {
+               if (hdcp_ddc_read(HDCP_RX_BCAPS_ADDR,
+                               bcaps, HDCP_RX_BCAPS_SIZE) == true)
+                       ret = true;
+       }
+       return ret;
+}
+
+static bool hdcp_read_bstatus(uint16_t *bstatus)
+{
+       bool ret = false;
+       if (bstatus != NULL) {
+               if (hdcp_ddc_read(HDCP_RX_BSTATUS_ADDR,
+                       (uint8_t *)bstatus, HDCP_RX_BSTATUS_SIZE) == true)
+                       ret = true;
+       }
+       return ret;
+}
+
+static bool hdcp_read_rx_ri(uint16_t *rx_ri)
+{
+       bool ret = false;
+       if (rx_ri != NULL) {
+               if (hdcp_ddc_read(HDCP_RX_RI_ADDR,
+                               (uint8_t *)rx_ri, HDCP_RI_SIZE) == true)
+                       ret = true;
+       }
+       return ret;
+}
+
+static bool hdcp_read_rx_r0(uint16_t *rx_r0)
+{
+       return hdcp_read_rx_ri(rx_r0);
+}
+
+static bool hdcp_stage3_ri_check(void)
+{
+       uint16_t rx_ri = 0;
+
+       if (hdcp_enable_condition_ready() == false ||
+           hdcp_context->is_enabled == false)
+               return false;
+
+#ifdef OTM_HDCP_DEBUG_MODULE
+       if (module_force_ri_mismatch) {
+               pr_debug("hdcp: force Ri mismatch\n");
+               module_force_ri_mismatch = false;
+               return false;
+       }
+#endif
+
+       if (hdcp_read_rx_ri(&rx_ri) == true)
+               if (ipil_hdcp_does_ri_match(rx_ri) == true)
+                       /* pr_debug("hdcp: Ri Matches %04x\n", rx_ri);*/
+                       return true;
+
+       pr_debug("hdcp: error!!!  Ri check failed %x\n", rx_ri);
+       return false;
+}
+
+static bool hdcp_send_an_aksv(uint8_t *an, uint8_t an_size,
+                       uint8_t *aksv, uint8_t aksv_size)
+{
+       bool ret = false;
+       if (an != NULL && an_size == HDCP_AN_SIZE &&
+          aksv != NULL  && aksv_size == HDCP_KSV_SIZE) {
+               if (hdcp_ddc_write(HDCP_RX_AN_ADDR, an, HDCP_AN_SIZE) ==
+                       true) {
+                       if (hdcp_ddc_write(HDCP_RX_AKSV_ADDR, aksv,
+                                       HDCP_KSV_SIZE) == true)
+                               ret = true;
+               }
+       }
+       return ret;
+}
+
+static void hdcp_reset(void)
+{
+       pr_debug("hdcp: reset\n");
+
+       /* TODO */
+       /* Stop Video if HDCP is still required */
+       /*      if (hdcp_context->is_required) */
+
+       /* Stop HDCP */
+       ipil_hdcp_disable();
+
+       hdcp_context->is_enabled = false;
+}
+
+static bool hdcp_rep_check(void)
+{
+       int msg = HDCP_REPEATER_CHECK;
+       return wq_send_message(msg, NULL);
+}
+
+static bool hdcp_rep_watch_dog(void)
+{
+       int msg = HDCP_REPEATER_WDT_EXPIRED;
+       return wq_send_message_delayed(msg, NULL, 5000);
+}
+
+static bool hdcp_initiate_rep_auth(void)
+{
+       pr_debug("hdcp: initiating repeater check\n");
+       hdcp_context->wdt_expired = false;
+       if (hdcp_rep_check() == true) {
+               if (hdcp_rep_watch_dog() == true)
+                       return true;
+               else
+                       pr_debug("hdcp: failed to start repeater wdt\n");
+       } else
+               pr_debug("hdcp: failed to start repeater check\n");
+       return false;
+}
+
+static bool hdcp_stage3_schedule_ri_check(void)
+{
+       int msg = HDCP_RI_CHECK;
+       return wq_send_message_delayed(msg, NULL, 2500);
+}
+
+static int hdcp_stage1_authentication(bool *is_repeater)
+{
+       uint8_t bksv[HDCP_KSV_SIZE], aksv[HDCP_KSV_SIZE], an[HDCP_AN_SIZE];
+       struct hdcp_rx_bstatus_t bstatus;
+       struct hdcp_rx_bcaps_t bcaps;
+       uint8_t retry = 0;
+       uint16_t rx_r0 = 0;
+
+       /* Read BKSV */
+       if (hdcp_read_bksv(bksv, HDCP_KSV_SIZE) == false)
+               return false;
+       pr_debug("hdcp: bksv: %02x%02x%02x%02x%02x\n",
+               bksv[0], bksv[1], bksv[2], bksv[3], bksv[4]);
+
+       /* Read An AKSV */
+       if (ipil_hdcp_get_an(an, HDCP_AN_SIZE) == false)
+               return false;
+       pr_debug("hdcp: an: %02x%02x%02x%02x%02x%02x%02x%02x\n",
+               an[0], an[1], an[2], an[3], an[4], an[5], an[6], an[7]);
+
+       if (hdcp_get_aksv(aksv, HDCP_KSV_SIZE) == false)
+               return false;
+       pr_debug("hdcp: aksv: %02x%02x%02x%02x%02x\n",
+                       aksv[0], aksv[1], aksv[2], aksv[3], aksv[4]);
+
+       /* Write An AKSV to Downstream Rx */
+       if (hdcp_send_an_aksv(an, HDCP_AN_SIZE, aksv, HDCP_KSV_SIZE)
+                                               == false)
+               return false;
+       pr_debug("hdcp: sent an aksv\n");
+
+       /* Read BCAPS & BKSV */
+       if (hdcp_read_bksv(bksv, HDCP_KSV_SIZE) == false)
+               return false;
+       pr_debug("hdcp: bksv: %02x%02x%02x%02x%02x\n",
+                       bksv[0], bksv[1], bksv[2], bksv[3], bksv[4]);
+
+       if (hdcp_read_bcaps(&bcaps.value) == false)
+               return false;
+       pr_debug("hdcp: bcaps: %x\n", bcaps.value);
+
+       /* Read BSTATUS */
+       if (hdcp_read_bstatus(&bstatus.value) == false)
+               return false;
+       pr_debug("hdcp: bstatus: %04x\n", bstatus.value);
+
+       /* Update repeater present status */
+       *is_repeater = bcaps.is_repeater;
+
+       /* Set Repeater Bit */
+       if (ipil_hdcp_set_repeater(bcaps.is_repeater) == false)
+               return false;
+
+       /* Write BKSV to Self */
+       if (ipil_hdcp_set_bksv(bksv) == false)
+               return false;
+
+       pr_debug("hdcp: set repeater & bksv\n");
+
+       /* Start First Stage of Authenticatioin */
+       if (ipil_hdcp_start_authentication() == false)
+               return false;
+
+       pr_debug("hdcp: auth started\n");
+
+       /* Wait for 100ms */
+       msleep_interruptible(100);
+
+       /* Check if R0 Ready */
+       retry = 20;
+       do {
+               if (ipil_hdcp_is_r0_ready() == true)
+                       break;
+               msleep_interruptible(5);
+               retry--;
+       } while (retry);
+
+       if (retry == 0 && ipil_hdcp_is_r0_ready() == false)
+               return false;
+
+       pr_debug("hdcp: R0 ready\n");
+
+       /* Read Ro' from Receiver */
+       if (hdcp_read_rx_r0(&rx_r0) == false)
+               return false;
+       pr_debug("hdcp: rx_r0 = %04x\n", rx_r0);
+
+       /* Check if R0 Matches */
+       if (ipil_hdcp_does_ri_match(rx_r0) == false)
+               return false;
+       pr_debug("hdcp: R0 matched\n");
+
+       /* Enable Encryption & Check status */
+       if (ipil_hdcp_enable_encryption() == false)
+               return false;
+       pr_debug("hdcp: encryption enabled\n");
+
+       hdcp_context->is_enabled = true;
+
+       return true;
+}
+
+static int hdcp_stage2_repeater_authentication(void)
+{
+       /* TODO: Repeater Authentication */
+       if (hdcp_enable_condition_ready() == false ||
+           hdcp_context->is_enabled == false ||
+           hdcp_context->wdt_expired == false)
+               return false;
+
+       /* check validity of repeater depth & device count */
+       /* check if fifo ready */
+       /* read ksv list */
+       /* verify SHA1 */
+       /* validate KSV's */
+       return true;
+}
+
+static bool hdcp_start(void)
+{
+       bool is_repeater = false;
+
+       pr_debug("hdcp: start\n");
+
+       /* Check HDCP Status */
+       if (ipil_hdcp_is_ready() == false)
+               return false;
+
+       if (hdcp_stage1_authentication(&is_repeater) == false)
+               return false;
+
+       pr_debug("hdcp: initial authentication completed, repeater:%d\n",
+               is_repeater);
+
+       /* Branch Repeater Mode Authentication */
+       if (is_repeater == true)
+               if (hdcp_initiate_rep_auth() == false)
+                       return false;
+
+       /* Branch Periodic Ri Check */
+       pr_debug("hdcp: starting periodic Ri check\n");
+       if (hdcp_stage3_schedule_ri_check() == false)
+               return false;
+
+       return true;
+}
+
+static void hdcp_retry_enable(void)
+{
+       int msg = HDCP_ENABLE;
+       if (hdcp_enable_condition_ready() == true &&
+               hdcp_context->is_enabled == false &&
+               hdcp_context->auto_retry == true) {
+               wq_send_message_delayed(msg, NULL, 30);
+               pr_debug("hdcp: retry enable\n");
+       }
+}
+
+static void hdcp_task_event_handler(struct work_struct *work)
+{
+       struct delayed_work *delayed_work = to_delayed_work(work);
+       struct hdcp_wq_struct_t *hwq = container_of(delayed_work,
+                                               struct hdcp_wq_struct_t,
+                                               dwork);
+       int msg = 0;
+       void *msg_data = NULL;
+       bool reset_hdcp = false;
+
+       if (hwq != NULL) {
+               msg = hwq->msg;
+               msg_data = hwq->msg_data;
+       }
+
+       if (hdcp_context == NULL || hwq == NULL)
+               goto EXIT_HDCP_HANDLER;
+
+       switch (msg) {
+       case HDCP_ENABLE:
+               if (hdcp_enable_condition_ready() == true &&
+                   hdcp_context->is_enabled == false &&
+                   hdcp_start() == false) {
+                       reset_hdcp = true;
+                       pr_debug("hdcp: failed to start hdcp\n");
+               }
+               break;
+
+       case HDCP_RI_CHECK:
+               /*pr_debug("hdcp: RI CHECK\n");*/
+               if (hdcp_stage3_ri_check() == false ||
+                   hdcp_stage3_schedule_ri_check() == false)
+                       reset_hdcp = true;
+               break;
+
+       case HDCP_REPEATER_CHECK:
+               pr_debug("hdcp: repeater check\n");
+               if (hdcp_stage2_repeater_authentication() == false)
+                       reset_hdcp = true;
+               break;
+
+       case HDCP_REPEATER_WDT_EXPIRED:
+               /* TODO */
+               hdcp_context->wdt_expired = true;
+               pr_debug("hdcp: repeater wdt expired\n");
+               break;
+
+       case HDCP_RESET:
+               hdcp_reset();
+               break;
+
+       case HDCP_SET_POWER_SAVE_STATUS:/* handle suspend resume */
+               if (msg_data != NULL) {
+                       hdcp_context->suspend = *((bool *)msg_data);
+                       pr_debug("hdcp: suspend = %d\n",
+                                       hdcp_context->suspend);
+                       if (hdcp_context->suspend == true) {
+                               if (hdcp_context->is_enabled == true)
+                                       reset_hdcp = true;
+                       }
+               }
+               break;
+
+       case HDCP_SET_HPD_STATUS:/* handle hpd status */
+               if (msg_data != NULL) {
+                       hdcp_context->hpd = *((bool *)msg_data);
+                       pr_debug("hdcp: hpd = %d\n",
+                                       hdcp_context->hpd);
+                       if (hdcp_context->hpd == false)
+                               reset_hdcp = true;
+               }
+               break;
+
+       case HDCP_SET_DPMS_STATUS:/* handle display_power_on status */
+               if (msg_data != NULL) {
+                       hdcp_context->display_power_on =
+                                       *((bool *)msg_data);
+                       pr_debug("hdcp: display_power_on = %d\n",
+                                       hdcp_context->display_power_on);
+                       if (hdcp_context->display_power_on == false)
+                               reset_hdcp = true;
+               }
+               break;
+
+       default:
+               break;
+       }
+
+       if (reset_hdcp == true) {
+               msg = HDCP_RESET;
+               wq_send_message(msg, NULL);
+       } else
+               /* if disabled retry HDCP authentication */
+               hdcp_retry_enable();
+EXIT_HDCP_HANDLER:
+       if (msg_data != NULL)
+               kfree(msg_data);
+       if (hwq != NULL)
+               kfree(hwq);
+
+       return;
+}
+
+/*
+ * Description: function to update HPD status
+ *
+ * @hpdi       HPD high/low status
+ *
+ * Returns:    true on success
+ *             false on failure
+ */
+bool otm_hdmi_hdcp_set_hpd_state(hdmi_context_t *hdmi_context,
+                                       bool hpd)
+{
+       int msg = HDCP_SET_HPD_STATUS;
+       bool *p_hpd = NULL;
+       hpd = !!(hpd);
+
+       if (hdmi_context == NULL || hdcp_context == NULL)
+               return false;
+
+       if (hdcp_context->hpd != hpd) {
+               p_hpd = kmalloc(sizeof(bool), GFP_KERNEL);
+               if (p_hpd != NULL) {
+                       *p_hpd = hpd;
+                       return wq_send_message(msg, (void *)p_hpd);
+               } else
+                       pr_debug("hdcp: %s failed to alloc mem\n", __func__);
+       }
+
+       return false;
+}
+
+/*
+ * Description: function to update power save (suspend/resume) status
+ *
+ * @suspend    suspend/resume status
+ *
+ * Returns:    true on success
+ *             false on failure
+ */
+bool otm_hdmi_hdcp_set_power_save(hdmi_context_t *hdmi_context,
+                                       bool suspend)
+{
+       int msg = HDCP_SET_POWER_SAVE_STATUS;
+       bool *p_suspend = NULL;
+       suspend = !!(suspend);
+
+       if (hdmi_context == NULL || hdcp_context == NULL)
+               return false;
+
+       if (hdcp_context->suspend != suspend) {
+               p_suspend = kmalloc(sizeof(bool), GFP_KERNEL);
+               if (p_suspend != NULL) {
+                       *p_suspend = suspend;
+                       return wq_send_message(msg, (void *)p_suspend);
+               } else
+                       pr_debug("hdcp: %s failed to alloc mem\n", __func__);
+               if (suspend == true)
+                       /* Cleanup WorkQueue */
+                       /* TODO: Needs Cosai Calls */
+                       flush_workqueue(hdcp_context->hdcp_wq);
+       }
+
+       return false;
+}
+
+/*
+ * Description: function to update display_power_on status
+ *
+ * @display_power_on   display power on/off status
+ *
+ * Returns:    true on success
+ *             false on failure
+ */
+bool otm_hdmi_hdcp_set_dpms(hdmi_context_t *hdmi_context,
+                       bool display_power_on)
+{
+       int msg = HDCP_SET_DPMS_STATUS;
+       bool *p_display_power_on = NULL;
+       display_power_on = !!(display_power_on);
+
+       if (hdmi_context == NULL || hdcp_context == NULL)
+               return false;
+
+       if (hdcp_context->display_power_on != display_power_on) {
+               p_display_power_on = kmalloc(sizeof(bool), GFP_KERNEL);
+               if (p_display_power_on != NULL) {
+                       *p_display_power_on = display_power_on;
+                       return wq_send_message(msg, (void *)p_display_power_on);
+               } else
+                       pr_debug("hdcp: %s failed to alloc mem\n", __func__);
+               if (display_power_on == false)
+                       /* Cleanup WorkQueue */
+                       /* TODO: Needs Cosai Calls */
+                       flush_workqueue(hdcp_context->hdcp_wq);
+       }
+       return false;
+}
+
+/*
+ * Description: function to enable HDCP
+ *
+ * Returns:    true on success
+ *             false on failure
+ */
+bool otm_hdmi_hdcp_enable(hdmi_context_t *hdmi_context)
+{
+       int msg = HDCP_ENABLE;
+
+       if (hdmi_context == NULL || hdcp_context == NULL)
+               return false;
+
+       if (hdcp_context->is_required == true) {
+               pr_debug("hdcp: already enabled\n");
+               return true;
+       }
+#ifdef OTM_HDCP_DEBUG_MODULE
+       if (module_disable_hdcp) {
+               pr_debug("hdcp: disabled by module\n");
+               return false;
+       }
+#endif
+       hdcp_context->is_required = true;
+
+       pr_debug("hdcp: enable\n");
+
+       return wq_send_message(msg, NULL);
+}
+
+/*
+ * Description: function to disable HDCP
+ *
+ * Returns:    true on success
+ *             false on failure
+ */
+bool otm_hdmi_hdcp_disable(hdmi_context_t *hdmi_context)
+{
+       int msg = HDCP_RESET;
+
+       if (hdmi_context == NULL || hdcp_context == NULL)
+               return false;
+
+       if (hdcp_context->is_required == false) {
+               pr_debug("hdcp: already disabled\n");
+               return true;
+       }
+
+       wq_send_message(msg, NULL);
+
+       /* Cleanup WorkQueue */
+       /* TODO: Needs Cosai Calls */
+       flush_workqueue(hdcp_context->hdcp_wq);
+
+       hdcp_context->is_required = false;
+
+       pr_debug("hdcp: disable\n");
+
+       return true;
+}
+
+/*
+ * Description: hdcp init function
+ *
+ * @ddc_rd_wr: pointer to ddc read write function
+ *
+ * Returns:    true on success
+ *             false on failure
+ */
+bool otm_hdmi_hdcp_init(hdmi_context_t *hdmi_context,
+       int (*ddc_rd_wr)(bool, uint8_t, uint8_t, uint8_t *, int))
+{
+       if (hdmi_context == NULL ||
+           ddc_rd_wr == NULL ||
+           ipil_hdcp_device_can_authenticate() == false ||
+           hdcp_context != NULL) {
+               pr_debug("hdcp: init error!!! parameters\n");
+               return false;
+       }
+
+       hdcp_context = kmalloc(sizeof(struct hdcp_context_t), GFP_KERNEL);
+       hdcp_context->hdcp_wq = NULL;
+
+       if (hdcp_context != NULL)
+               hdcp_context->hdcp_wq = create_workqueue("HDCP_WQ");
+
+       if (hdcp_context == NULL || hdcp_context->hdcp_wq == NULL) {
+               pr_debug("hdcp: init error!!! allocation\n");
+               goto EXIT_INIT;
+       }
+
+       hdcp_context->is_required       = false;
+       hdcp_context->is_enabled        = false;
+       hdcp_context->suspend           = false;
+       hdcp_context->hpd               = false;
+       hdcp_context->display_power_on  = false;
+       hdcp_context->auto_retry        = true;
+       hdcp_context->wdt_expired       = false;
+       hdcp_context->can_authenticate  = true;
+       hdcp_context->current_srm_ver   = 0u;
+       hdcp_context->vrl               = NULL;
+       hdcp_context->vrl_count         = 0u;
+
+       hdcp_context->ddc_read_write = ddc_rd_wr;
+
+       if (ipil_hdcp_init() == true) {
+               pr_debug("hdcp: initialized\n");
+               return true;
+       }
+EXIT_INIT:
+       /* Cleanup and exit */
+       if (hdcp_context != NULL) {
+               if (hdcp_context->hdcp_wq != NULL)
+                       destroy_workqueue(hdcp_context->hdcp_wq);
+               kfree(hdcp_context);
+               hdcp_context = NULL;
+       }
+
+       return false;
+}
+
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/common/hdmi_internal.h b/drivers/staging/mrst/drv/otm_hdmi/pil/common/hdmi_internal.h
new file mode 100644 (file)
index 0000000..ecd7a7e
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef _OTM_HDMI_INTERNAL_H
+#define _OTM_HDMI_INTERNAL_H
+
+
+#include <linux/time.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+
+#include "otm_hdmi_types.h"
+#include "otm_hdmi_defs.h"
+
+#include "edid.h"
+#include "hdmi_hal.h"
+
+/**
+ * Defines, shortcuts and globals
+ */
+
+extern otm_hdmi_attribute_t
+       otm_hdmi_attributes_table[OTM_HDMI_MAX_SUPPORTED_ATTRIBUTES];
+
+#define ATTRS otm_hdmi_attributes_table
+
+/* Note: this macro should **only** be used when time difference is less than
+ * 4s */
+#define TIME_DIFF(tv2, tv1) ((((tv2).tv_sec - (tv1).tv_sec) * 1000000) + \
+                            ((tv2).tv_usec - (tv1).tv_usec))
+
+#define GPIO_MIN 0
+#define GPIO_MAX 28
+
+#define I2C_HW_TIMEOUT TIME_MS(200)
+#define I2C_SW_TIMEOUT 500
+
+#define CURRENT_DMA_READ_DESCRIPTOR(ai) \
+(((hdmi_dma_descriptor_t *) (ai)->dscr_buf_addr_v)[(ai)->dscr_current_r])
+
+#define NUM_ENTRIES_IN(set) (sizeof(set) / sizeof(*set))
+
+#define ALL_SF (OTM_HDMI_AUDIO_FS_192_KHZ   | \
+               OTM_HDMI_AUDIO_FS_176_4_KHZ | \
+               OTM_HDMI_AUDIO_FS_96_KHZ    | \
+               OTM_HDMI_AUDIO_FS_88_2_KHZ  | \
+               OTM_HDMI_AUDIO_FS_48_KHZ    | \
+               OTM_HDMI_AUDIO_FS_44_1_KHZ  | \
+               OTM_HDMI_AUDIO_FS_32_KHZ)
+
+#define ALL_SS (OTM_HDMI_AUDIO_SS_16 | \
+               OTM_HDMI_AUDIO_SS_20 | \
+               OTM_HDMI_AUDIO_SS_24)
+
+#define DECLARE_AUDIO_CAP(_fmt, _nch, _fs, _ss) \
+       { .format = _fmt, .max_channels = _nch, .fs = _fs, .ss_bitrate = _ss }
+
+/**
+ * Interrupts grouped by use
+ */
+#define HDMI_INTERRUPTS (HDMI_INTERRUPT_I2C_BUS_ERROR   | \
+                        HDMI_INTERRUPT_I2C_BUFFER_FULL       | \
+                        HDMI_INTERRUPT_I2C_TRANSACTION_DONE  | \
+                        HDMI_INTERRUPT_HDCP_KEYS_READY       | \
+                        HDMI_INTERRUPT_HDCP_RI        | \
+                        HDMI_INTERRUPT_HDCP_PI        | \
+                        HDMI_INTERRUPT_HDCP_FRAME          | \
+                        HDMI_INTERRUPT_HDCP_M0        | \
+                        HDMI_INTERRUPT_HDCP_R0        | \
+                        HDMI_INTERRUPT_AUDIO_FIFO_UNDERFLOW  | \
+                        HDMI_INTERRUPT_DMA_SRC_COMPLETE      | \
+                        HDMI_INTERRUPT_HOTPLUG_DETECT) /* Enable HPD */
+
+/**
+ * Infoframe slot aliases
+ */
+enum {
+       PACKET_SLOT_AVI = 0,
+       PACKET_SLOT_AUDIO = 1,
+       PACKET_SLOT_GENERIC_0 = 2,
+       PACKET_SLOT_GENERIC_1 = 3,
+};
+
+/**
+ * Infoframe Transmission Frequency
+ */
+enum {
+       HDMI_DIP_SEND_ONCE = 0,
+       HDMI_DIP_SEND_EVERY_VSYNC = 1,
+       HDMI_DIP_SEND_ATLEAST_EVERY_OTHER_VSYNC = 2,
+};
+
+/**
+ * Supported packets
+ */
+typedef enum {
+       HDMI_PACKET_NULL = 0x00,
+       HDMI_PACKET_ACP = 0x04,
+       HDMI_PACKET_ISRC1 = 0x05,
+       HDMI_PACKET_ISRC2 = 0x06,
+       HDMI_PACKET_GAMUT = 0x0A,
+       HDMI_PACKET_VS = 0x81,
+       HDMI_PACKET_AVI = 0x82,
+       HDMI_PACKET_SPD = 0x83,
+} hdmi_packet_type_t;
+
+/**
+ * Packet management info
+ */
+typedef struct {
+       otm_hdmi_packet_t packet;
+       bool int_use;
+} packet_info_t;
+
+/**
+ * HDMI AV mute source
+ */
+typedef enum {
+       MUTE_SOURCE_HDCP = 0x01,
+       MUTE_SOURCE_APP = 0x02,
+} mute_source_t;
+
+/**
+ * This structure represents typical "enumerator - value" pair
+ */
+typedef struct {
+       int e;
+       int v;
+} ev_t;
+
+/**
+ * Audio setup information
+ */
+typedef struct {
+       unsigned int dscr_buf_addr;     /* DMA descriptors buffer physical
+                                          address */
+       void *dscr_buf_addr_v;          /* DMA descriptors buffer virtual
+                                          address */
+       unsigned int dscr_buf_size;     /* DMA descriptors buffer size */
+       unsigned int dscr_current_w;    /* index of current write descriptor */
+       unsigned int dscr_current_r;    /* index of current read descriptor */
+       bool playback;          /* playback status */
+       bool prebuffer;         /* prebuffering status */
+
+       otm_hdmi_audio_fmt_t fmt;       /* format */
+       otm_hdmi_audio_fs_t fs;         /* sampling frequency */
+       unsigned int nch;               /* number of channels */
+       otm_hdmi_audio_ss_t ss;         /* sample size */
+       unsigned int map;               /* speaker allocation map */
+       unsigned int chst[2];           /* channel status info */
+       bool hbr;               /* HBR vs non-HBR transmission mode */
+       otm_hdmi_audio_fs_t fs_adj;     /* audio frame rate */
+} audio_info_t;
+
+/**
+ * HDMI context definition
+ */
+typedef struct {
+       hdmi_device_t dev;      /* hdmi hal handle */
+       void *io_address;       /* address of mapped io region */
+       unsigned int io_length; /* size of io region */
+
+       edid_info_t edid_ext;   /* external EDID structure */
+       edid_info_t edid_int;   /* internal EDID structure */
+       char edid_raw[MAX_EDID_BLOCKS*SEGMENT_SIZE];     /* raw EDID data */
+
+       otm_hdmi_timing_t mode; /* current mode */
+       bool mode_set;  /* mode switch completion indicator */
+       bool hdmi;      /* active transmission type */
+
+       void *hdcp;     /* HDCP library handle */
+       bool hdcp_1p1;  /* HDCP 1.1 support */
+
+       unsigned int irq_number;        /* IRQ number */
+       void *thread_hpd;       /* hot plug thread handler */
+       struct mutex modes_sema;        /* protecting modes table sharing */
+       struct mutex exec_sema; /* to sync pd entries execution */
+       struct mutex i2c_sema;  /* i2c access synchronization semaphore */
+       struct mutex hpd_sema;  /* semaphore to sync hot plug sensetive data */
+       struct mutex srv_sema;  /* semaphore to sync service and main threads */
+       struct mutex mute_sema; /* to sync av mute operations */
+
+       bool phy_status;/* current HW PHY status */
+       bool ph2_active;/* indicates whether hdcp ph2 is in progress */
+       bool ph1_cancel;/* indicates need to cancel current phase 1 */
+       bool dtv;       /* TX vs DTV indicator */
+       bool dc;        /* Deep Color enable indicator */
+       bool hw_i2c;    /* I2C HW acceleration indicator */
+
+       struct timeval ph2_start;       /* start time of hdcp auth phase #2 */
+       struct timeval phy_time;        /* PHY enabling countdown reference */
+       struct timeval hpe_time;        /* last time of any hot plug event */
+       struct timeval hal_timer;       /* HAL polling timer */
+
+       packet_info_t pi_0;     /* data to be sent via 1st available slot */
+       packet_info_t pi_1;     /* data to be sent via 2nd available slot */
+       packet_info_t pi_avi;   /* data to be sent via AVI slot */
+
+       unsigned int gpio;      /* GPIO ID for I2C workaround */
+       unsigned char ksvs[635];        /* list of downstream ksvs */
+       bool ef_int_pend;       /* encrypted frame interrupt indicator
+                                       */
+       bool usr_avi;   /* indicator for user-defn AVI */
+       int n_modes_tx;         /* number of static modes */
+       int n_modes_ref;        /* number of reference modes */
+
+       int mode_width;  /* selected mode width */
+       int mode_height; /* selected mode height */
+
+       audio_info_t audio_info;        /* hdmi audio unit information */
+       mute_source_t mute_source;      /* current mute sources list */
+
+       otm_hdmi_phy_info_t phy_info;   /* Current PHY electrical properties */
+       otm_hdmi_hdcp_info_t hdcp_info; /* HDCP debug information */
+} hdmi_context_t;
+
+/* mapping structures between pil and ipil */
+typedef        otm_hdmi_timing_t ipil_timings_t;
+
+/* scaling types */
+#define IPIL_TIMING_SCALE_NONE         0 /* Unmodified timing (display or
+                                               software can still scale) */
+#define IPIL_TIMING_SCALE_FULLSCREEN   1 /* Full screen, ignore aspect */
+#define IPIL_TIMING_SCALE_CENTER       2 /* Centered, no scaling */
+#define IPIL_TIMING_SCALE_ASPECT       3 /* Full screen, preserve aspect */
+
+/* HDMI attributes setup routine */
+typedef otm_hdmi_ret_t(*pd_attr_declare_t)(otm_hdmi_attribute_t *table,
+                                       otm_hdmi_attribute_id_t id,
+                                       otm_hdmi_attribute_type_t type,
+                                       otm_hdmi_attribute_flag_t flags,
+                                       char *name,
+                                       void *value,
+                                       unsigned int min,
+                                       unsigned int max);
+
+otm_hdmi_ret_t otm_hdmi_declare_attributes(pd_attr_declare_t declare,
+                                       pd_attr_get_name_t get_name);
+
+otm_hdmi_ret_t hdmi_timing_add_twin_entries(edid_info_t *edid,
+                                           otm_hdmi_refresh_t src,
+                                           otm_hdmi_refresh_t dst);
+
+void hdmi_timing_edid_to_vdc(otm_hdmi_timing_t *t);
+
+#endif /* _OTM_HDMI_INTERNAL_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/common/hdmi_timings.h b/drivers/staging/mrst/drv/otm_hdmi/pil/common/hdmi_timings.h
new file mode 100644 (file)
index 0000000..97b8d6e
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ This file is provided under a dual BSD/GPLv2 license.  When using or
+ redistributing this file, you may do so under either license.
+
+ GPL LICENSE SUMMARY
+
+ Copyright(c) 2006-2011 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ 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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+ The full GNU General Public License is included in this distribution
+ in the file called LICENSE.GPL.
+
+ Contact Information:
+      Intel Corporation
+      2200 Mission College Blvd.
+      Santa Clara, CA  97052
+
+ BSD LICENSE
+
+ Copyright(c) 2006-2011 Intel Corporation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   - Neither the name of Intel Corporation nor the names of its
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+
+#ifndef __HDMI_TIMINGS_H__
+#define __HDMI_TIMINGS_H__
+
+#include "otm_hdmi.h"
+
+extern const otm_hdmi_timing_t MODE_640x480p5994_60;
+extern const otm_hdmi_timing_t MODE_720x480p5994_60;
+extern const otm_hdmi_timing_t MODE_720x480p5994_60__16by9;
+extern const otm_hdmi_timing_t MODE_1280x720p5994_60;
+extern const otm_hdmi_timing_t MODE_1920x1080i5994_60;
+extern const otm_hdmi_timing_t MODE_1920x1080i5994_60__FP;
+extern const otm_hdmi_timing_t MODE_720_1440x480i5994_60;
+extern const otm_hdmi_timing_t MODE_720_1440x480i5994_60__16by9;
+extern const otm_hdmi_timing_t MODE_1920x1080p5994_60;
+extern const otm_hdmi_timing_t MODE_720x576p50;
+extern const otm_hdmi_timing_t MODE_720x576p50__16by9;
+extern const otm_hdmi_timing_t MODE_1280x720p50;
+extern const otm_hdmi_timing_t MODE_1920x1080i50;
+extern const otm_hdmi_timing_t MODE_1920x1080i50__FP;
+extern const otm_hdmi_timing_t MODE_720_1440x576i50;
+extern const otm_hdmi_timing_t MODE_720_1440x576i50__16by9;
+extern const otm_hdmi_timing_t MODE_1920x1080p50;
+extern const otm_hdmi_timing_t MODE_1920x1080p24;
+extern const otm_hdmi_timing_t MODE_1920x1080p25;
+extern const otm_hdmi_timing_t MODE_1920x1080p30;
+extern const otm_hdmi_timing_t MODE_1920x1080p30__FP2;
+extern const otm_hdmi_timing_t MODE_1920x1080p30__FP;
+extern const otm_hdmi_timing_t MODE_1920x1080p30__TBH2;
+extern const otm_hdmi_timing_t MODE_1920x1080p48;
+extern const otm_hdmi_timing_t MODE_1920x1080p24__FP2;
+extern const otm_hdmi_timing_t MODE_1920x1080p24__FP;
+extern const otm_hdmi_timing_t MODE_1280x720p5994_60__FP2;
+extern const otm_hdmi_timing_t MODE_1280x720p5994_60__FP;
+extern const otm_hdmi_timing_t MODE_1280x720p50__FP2;
+extern const otm_hdmi_timing_t MODE_1280x720p50__FP;
+extern const otm_hdmi_timing_t MODE_1280x720p5994_60__SBSH2;
+extern const otm_hdmi_timing_t MODE_1280x720p50__SBSH2;
+extern const otm_hdmi_timing_t MODE_1920x1080i5994_60__SBSH2;
+extern const otm_hdmi_timing_t MODE_1920x1080i50__SBSH2;
+extern const otm_hdmi_timing_t MODE_1920x1080p5994_60__SBSH2;
+extern const otm_hdmi_timing_t MODE_1920x1080p50__SBSH2;
+extern const otm_hdmi_timing_t MODE_1920x1080p24__SBSH2;
+extern const otm_hdmi_timing_t MODE_1280x720p5994_60__TBH2;
+extern const otm_hdmi_timing_t MODE_1280x720p50__TBH2;
+extern const otm_hdmi_timing_t MODE_1920x1080p5994_60__TBH2;
+extern const otm_hdmi_timing_t MODE_1920x1080p50__TBH2;
+extern const otm_hdmi_timing_t MODE_1920x1080p24__TBH2;
+extern const otm_hdmi_timing_t MODE_1280x720p60__PANEL_FS;
+extern const otm_hdmi_timing_t MODE_1280x720p50__PANEL_FS;
+extern const otm_hdmi_timing_t MODE_1920x540p60__PANEL_FS;
+extern const otm_hdmi_timing_t MODE_1920x540p50__PANEL_FS;
+extern const otm_hdmi_timing_t MODE_920x1080p60__PANEL_FS;
+extern const otm_hdmi_timing_t MODE_920x1080p50__PANEL_FS;
+extern const otm_hdmi_timing_t MODE_1920x1080p30__PANEL_FS;
+extern const otm_hdmi_timing_t MODE_1920x1080p25__PANEL_FS;
+extern const otm_hdmi_timing_t MODE_1920x1080p24__PANEL_FS;
+extern const otm_hdmi_timing_t MODE_1920x1080p60__PANEL;
+extern const otm_hdmi_timing_t MODE_1920x1080p50__PANEL;
+extern const otm_hdmi_timing_t MODE_1920x1080p48__PANEL;
+#endif /* __HDMI_TIMINGS_H_ */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/common/infoframes.c b/drivers/staging/mrst/drv/otm_hdmi/pil/common/infoframes.c
new file mode 100644 (file)
index 0000000..a6b9413
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+       Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+       Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include "otm_hdmi.h"
+#include "ipil_hdmi.h"
+
+#include "hdmi_internal.h"
+#include "hdmi_timings.h"
+
+
+/**
+ * This enumeration represents possible color space settings found in GBD
+ * Current driver logic assumes we only support colorimetries that can be
+ * advertised in EDID: xvYCC601 and xvYCC709
+ */
+enum {
+       GBD_CS_ITU_BT709 = 0,
+       GBD_CS_XVYCC601 = 1,
+       GBD_CS_XVYCC709 = 2,
+       GBD_CS_XYZ = 3,
+       GBD_CS_RESERVED = 4,
+};
+
+static int __compute_check_sum(otm_hdmi_packet_t *packet)
+{
+       uint8_t i = 0;
+       uint8_t sum = 0;
+
+       for (i = 0; i < 3; i++)
+               sum += packet->header[i];
+       for (i = 1; i < 28; i++)
+               sum += packet->data[i];
+
+       packet->data[0] = (uint8_t)(0xFF - sum + 1);
+
+       return (int)packet->data[0];
+}
+
+/**
+ * Note: higher level ensures that input value is valid
+ */
+static int __pfconvert(otm_hdmi_output_pixel_format_t pf)
+{
+       int rc = 0;     /* init to RGB444 */
+
+       switch (pf) {
+       case OTM_HDMI_OPF_RGB444:
+               rc = 0;
+               break;
+       case OTM_HDMI_OPF_YUV422:
+               rc = 1;
+               break;
+       case OTM_HDMI_OPF_YUV444:
+               rc = 2;
+               break;
+       default:
+               rc = 0;
+               break;
+       }
+
+       return rc;
+}
+
+otm_hdmi_ret_t hdmi_packet_check_type(otm_hdmi_packet_t *p,
+                                       hdmi_packet_type_t type)
+{
+       return ((p && p->header[0] == type) ?
+               OTM_HDMI_SUCCESS : OTM_HDMI_ERR_FAILED);
+}
+
+/*
+ * Description: set avi infoframe based on mode
+ *
+ * @context:   hdmi_context
+ * @mode:      mode requested
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t otm_hdmi_infoframes_set_avi(void *context,
+                                       otm_hdmi_timing_t *mode)
+{
+       hdmi_context_t *ctx = (hdmi_context_t *)context;
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       unsigned int type = HDMI_PACKET_AVI;
+       unsigned int freq = HDMI_DIP_SEND_EVERY_VSYNC;
+       int cs = GBD_CS_XVYCC601;
+       otm_hdmi_packet_t avi_pkt;
+       unsigned int pf, vic;
+       bool p, ext;
+       otm_hdmi_par_t par = PD_ATTR_UINT(ATTRS[OTM_HDMI_ATTR_ID_PAR]);
+
+       if (!context || !mode) {
+               pr_debug("\ninvalid arguments\n");
+               return OTM_HDMI_ERR_NULL_ARG;
+       }
+
+       /* Set header to AVI */
+       avi_pkt.header[0] = 0x82;
+       avi_pkt.header[1] = 0x02;
+       avi_pkt.header[2] = 0x0D;
+       /* Clear payload section */
+       memset(avi_pkt.data, 0, sizeof(avi_pkt.data));
+
+       /* RGB, Active Format Info valid, no bars */
+       /* use underscan as HDMI video is composed with all
+        * active pixels and lines with or without border
+        */
+       avi_pkt.data[1] = 0x12;
+       /* Set color component sample format */
+       pf = __pfconvert(PD_ATTR_UINT
+                        (ATTRS[OTM_HDMI_ATTR_ID_PIXEL_FORMAT_OUTPUT]));
+       avi_pkt.data[1] |= pf << 5;
+       /* Colorimetry */
+       ext = PD_ATTR_BOOL(ATTRS[OTM_HDMI_ATTR_ID_COLOR_SPACE_EXT]);
+       avi_pkt.data[2] =
+           (ext ? 3 : (!pf ? 0 : ((mode->width <= 720) ? 0x01 : 0x02))) << 6;
+       /* Fill PAR for all supported modes
+        * This is required for passing compliance tests
+        */
+       switch (mode->metadata) {
+       case 1: /* 640x480p60   */
+       case 2: /* 720x480p60   */
+       case 17:/* 720x576p50   */
+               /* Fall Through */
+               par = OTM_HDMI_PAR_4_3; break;
+       case 3: /* 720x480p60   */
+       case 4: /* 1280x720p60  */
+       case 16:/* 1920x1080p60 */
+       case 18:/* 720x576p50   */
+       case 19:/* 1280x720p50  */
+       case 32:/* 1920x1080p24 */
+       case 33:/* 1920x1080p25 */
+       case 34:/* 1920x1080p30 */
+               /* Fall Through */
+               par = OTM_HDMI_PAR_16_9; break;
+       default:
+               break;
+       }
+       avi_pkt.data[2] |= par << 4;
+       /* Fill FAR */
+       avi_pkt.data[2] |= PD_ATTR_UINT(ATTRS[OTM_HDMI_ATTR_ID_FAR]);
+
+       /* Get extended colorimetry from slot 1 */
+       if (hdmi_packet_check_type(&ctx->pi_1.packet, HDMI_PACKET_GAMUT) ==
+           OTM_HDMI_SUCCESS)
+               cs = ctx->pi_1.packet.data[0] & 0x07;
+       /* Get extended colorimetry from slot 0 */
+       else if (hdmi_packet_check_type(&ctx->pi_0.packet, HDMI_PACKET_GAMUT) ==
+                OTM_HDMI_SUCCESS)
+               cs = ctx->pi_0.packet.data[0] & 0x07;
+
+       /* Fill extended colorimetry */
+       avi_pkt.data[3] = ((cs == GBD_CS_XVYCC601) ? 0 : 1) << 4;
+
+       /* Fill quantization range */
+       if (ctx->edid_int.rgb_quant_selectable
+           && PD_ATTR_UINT(ATTRS[OTM_HDMI_ATTR_ID_PIXEL_FORMAT_OUTPUT]) ==
+           OTM_HDMI_OPF_RGB444)
+               avi_pkt.data[3] |=
+                       PD_ATTR_BOOL(ATTRS[OTM_HDMI_ATTR_ID_OUTPUT_CLAMP]) ?
+                       (0x01 << 2) : (0x02 << 2);
+
+       /* Fill Video Identification Code [adjust VIC according to PAR] */
+       vic = mode->metadata;
+#ifdef OTM_HDMI_FIXME
+       /* TODO: use this when PAR value gets updated in get attributes */
+       /* and reverify the VIC & PAR settings */
+       avi_pkt.data[4] = vic +
+               ((mode->width == 720 && par == OTM_HDMI_PAR_16_9) ? 1 : 0);
+#else
+       avi_pkt.data[4] = vic;
+#endif
+
+       /* Fill pixel repetition value: 2x for 480i and 546i */
+       p = ((mode->mode_info_flags & PD_SCAN_INTERLACE) == 0);
+       avi_pkt.data[5] = ((mode->width == 720) && !p) ? 0x01 : 0x00;
+       /* Fill quantization range */
+       if (ctx->edid_int.ycc_quant_selectable
+           && (PD_ATTR_UINT(ATTRS[OTM_HDMI_ATTR_ID_PIXEL_FORMAT_OUTPUT]) ==
+                                                       OTM_HDMI_OPF_YUV444 ||
+               PD_ATTR_UINT(ATTRS[OTM_HDMI_ATTR_ID_PIXEL_FORMAT_OUTPUT]) ==
+                                                       OTM_HDMI_OPF_YUV422))
+               avi_pkt.data[5] |=
+                       PD_ATTR_BOOL(ATTRS[OTM_HDMI_ATTR_ID_OUTPUT_CLAMP]) ?
+                       (0x00 << 6) : (0x01 << 6);
+
+       /* Compute and fill checksum */
+       avi_pkt.data[0] = __compute_check_sum(&avi_pkt);
+
+       /* Enable AVI infoframe */
+       rc = ipil_hdmi_enable_infoframe(&ctx->dev, type, &avi_pkt, freq);
+
+       return rc;
+}
+
+/*
+ * Description: disable all infoframes
+ *
+ * @context:        hdmi_context
+ *
+ * Returns:     OTM_HDMI_ERR_NULL_ARG on NULL parameters
+ *              OTM_HDMI_SUCCESS on success
+*/
+otm_hdmi_ret_t otm_hdmi_disable_all_infoframes(void *context)
+{
+       hdmi_context_t *ctx = (hdmi_context_t *)context;
+       if (!ctx)
+               return OTM_HDMI_ERR_NULL_ARG;
+
+       return ipil_hdmi_disable_all_infoframes(&ctx->dev);
+}
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/common/infoframes_api.h b/drivers/staging/mrst/drv/otm_hdmi/pil/common/infoframes_api.h
new file mode 100644 (file)
index 0000000..8dd1a39
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef _INFOFRAMES_API_H
+#define _INFOFRAMES_API_H
+
+/*
+ * Description: set avi infoframe based on mode
+ *
+ * @context:            hdmi_context
+ * @mode:               mode requested
+ *
+ * Returns:     OTM_HDMI_SUCCESS on success
+ *              OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+extern otm_hdmi_ret_t otm_hdmi_infoframes_set_avi(void *context,
+                                       otm_hdmi_timing_t *mode);
+
+/*
+ * Description:        disable all infoframes
+ *
+ * @context:   hdmi_context
+ *
+ * Returns:    OTM_HDMI_ERR_NULL_ARG on NULL parameters
+ *             OTM_HDMI_SUCCESS on success
+ */
+extern otm_hdmi_ret_t otm_hdmi_disable_all_infoframes(void *context);
+
+#endif /* _INFOFRAMES_API_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/common/mode_info.c b/drivers/staging/mrst/drv/otm_hdmi/pil/common/mode_info.c
new file mode 100644 (file)
index 0000000..fce6721
--- /dev/null
@@ -0,0 +1,1151 @@
+/*
+ This file is provided under a dual BSD/GPLv2 license.  When using or
+ redistributing this file, you may do so under either license.
+
+ GPL LICENSE SUMMARY
+
+ Copyright(c) 2006-2011 Intel Corporation. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of version 2 of the GNU General Public License as
+ published by the Free Software Foundation.
+
+ 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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+ The full GNU General Public License is included in this distribution
+ in the file called LICENSE.GPL.
+
+ Contact Information:
+      Intel Corporation
+      2200 Mission College Blvd.
+      Santa Clara, CA  97052
+
+ BSD LICENSE
+
+ Copyright(c) 2006-2011 Intel Corporation. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+   - Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   - Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   - Neither the name of Intel Corporation nor the names of its
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#include "hdmi_internal.h"
+#include "otm_hdmi_defs.h"
+
+/*-----------------------------------------------------------------------------
+                       480P TIMINGS
+-----------------------------------------------------------------------------*/
+#define TIMING_640x480p5994_60 \
+               640,            /* width        */ \
+               480,            /* height       */ \
+               OTM_HDMI_REFRESH_60, /* refresh rate */ \
+               25200,          /* clock        */ \
+               800,            /* htotal       */ \
+               640,            /* hblank start */ \
+               800,            /* hblank end   */ \
+               656,            /* hsync start  */ \
+               752,            /* hsync end    */ \
+               525,            /* vtotal       */ \
+               480,            /* vblank start */ \
+               525,            /* vblank end   */ \
+               490,            /* vsync start  */ \
+               492             /* vsync end    */
+
+
+#define TIMING_720x480p5994_60 \
+               720,            /* width        */ \
+               480,            /* height       */ \
+               OTM_HDMI_REFRESH_60, /* refresh rate */ \
+               27027,          /* clock        */ \
+               858,            /* htotal       */ \
+               720,            /* hblank start */ \
+               858,            /* hblank end   */ \
+               736,            /* hsync start  */ \
+               798,            /* hsync end    */ \
+               525,            /* vtotal       */ \
+               480,            /* vblank start */ \
+               525,            /* vblank end   */ \
+               489,            /* vsync start  */ \
+               495             /* vsync end    */
+
+/*-----------------------------------------------------------------------------
+                       576P TIMINGS
+-----------------------------------------------------------------------------*/
+#define TIMING_720x576p50 \
+               720,            /* width        */ \
+               576,            /* height       */ \
+               OTM_HDMI_REFRESH_50, /* refresh rate */ \
+               27000,          /* clock        */ \
+               864,            /* htotal       */ \
+               720,            /* hblank start */ \
+               864,            /* hblank end   */ \
+               732,            /* hsync start  */ \
+               796,            /* hsync end    */ \
+               625,            /* vtotal       */ \
+               576,            /* vblank start */ \
+               625,            /* vblank end   */ \
+               581,            /* vsync start  */ \
+               586             /* vsync end    */
+
+/*-----------------------------------------------------------------------------
+                       720I TIMINGS
+-----------------------------------------------------------------------------*/
+#define TIMING_720_1440x480i5994_60 \
+               1440,           /* width        */ \
+               240,            /* height       */ \
+               OTM_HDMI_REFRESH_60, /* refresh rate */ \
+               27027,          /* clock        */ \
+               1716,           /* htotal       */ \
+               1440,           /* hblank start */ \
+               1716,           /* hblank end   */ \
+               1478,           /* hsync start  */ \
+               1602,           /* hsync end    */ \
+               262,            /* vtotal       */ \
+               240,            /* vblank start */ \
+               262,            /* vblank end   */ \
+               244,            /* vsync start  */ \
+               247             /* vsync end    */
+
+#define TIMING_720_1440x576i50 \
+               1440,           /* width        */ \
+               288,            /* height       */ \
+               OTM_HDMI_REFRESH_50, /* refresh rate */ \
+               27000,          /* clock        */ \
+               1728,           /* htotal       */ \
+               1440,           /* hblank start */ \
+               1728,           /* hblank end   */ \
+               1464,           /* hsync start  */ \
+               1590,           /* hsync end    */ \
+               312,            /* vtotal       */ \
+               288,            /* vblank start */ \
+               312,            /* vblank end   */ \
+               290,            /* vsync start  */ \
+               293             /* vsync end    */
+
+/*-----------------------------------------------------------------------------
+                       720P TIMINGS
+-----------------------------------------------------------------------------*/
+#define TIMING_1280x720p50 \
+               1280,           /* width        */ \
+               720,            /* height       */ \
+               OTM_HDMI_REFRESH_50, /* refresh rate */ \
+               74250,          /* clock        */ \
+               1980,           /* htotal       */ \
+               1280,           /* hblank start */ \
+               1980,           /* hblank end   */ \
+               1720,           /* hsync start  */ \
+               1760,           /* hsync end    */ \
+               750,            /* vtotal       */ \
+               720,            /* vblank start */ \
+               750,            /* vblank end   */ \
+               725,            /* vsync start  */ \
+               730             /* vsync end    */
+
+#define TIMING_1280x720p50_FP \
+               1280,           /* width        */ \
+               720,            /* height       */ \
+               OTM_HDMI_REFRESH_50, /* refresh rate */ \
+               148500,  /* clock       */ \
+               1980,           /* htotal       */ \
+               1280,           /* hblank start */ \
+               1980,           /* hblank end   */ \
+               1720,           /* hsync start  */ \
+               1760,           /* hsync end    */ \
+               750,            /* vtotal       */ \
+               720,            /* vblank start */ \
+               750,            /* vblank end   */ \
+               725,            /* vsync start  */ \
+               730             /* vsync end    */
+
+#define TIMING_1280x720p50_FP2 \
+               1280,           /* width        */ \
+               720,            /* height       */ \
+               OTM_HDMI_REFRESH_50, /* refresh rate */ \
+               148500,         /* clock        */ \
+               1980,           /* htotal       */ \
+               1280,           /* hblank start */ \
+               1980,           /* hblank end   */ \
+               1720,           /* hsync start  */ \
+               1760,           /* hsync end    */ \
+               1500,           /* vtotal       */ \
+               1470,           /* vblank start */ \
+               1500,           /* vblank end   */ \
+               1475,           /* vsync start  */ \
+               1480            /* vsync end    */
+
+#define TIMING_1280x720p50_FSEQ \
+               1280,           /* width        */ \
+               720,            /* height       */ \
+               OTM_HDMI_REFRESH_50, /* refresh rate */ \
+               148500,         /* clock        */ \
+               1980,           /* htotal       */ \
+               1280,           /* hblank start */ \
+               1980,           /* hblank end   */ \
+               1720,           /* hsync start  */ \
+               1760,           /* hsync end    */ \
+               750,            /* vtotal       */ \
+               720,            /* vblank start */ \
+               750,            /* vblank end   */ \
+               725,            /* vsync start  */ \
+               730             /* vsync end    */
+
+#define TIMING_1280x720p5994_60 \
+               1280,           /* width        */ \
+               720,            /* height       */ \
+               OTM_HDMI_REFRESH_60, /* refresh rate */ \
+               74250,          /* clock        */ \
+               1650,           /* htotal       */ \
+               1280,           /* hblank start */ \
+               1650,           /* hblank end   */ \
+               1390,           /* hsync start  */ \
+               1430,           /* hsync end    */ \
+               750,            /* vtotal       */ \
+               720,            /* vblank start */ \
+               750,            /* vblank end   */ \
+               725,            /* vsync start  */ \
+               730             /* vsync end    */
+
+#define TIMING_1280x720p5994_60_FP \
+               1280,           /* width        */ \
+               720,            /* height       */ \
+               OTM_HDMI_REFRESH_60, /* refresh rate */ \
+               148500,         /* clock        */ \
+               1650,           /* htotal       */ \
+               1280,           /* hblank start */ \
+               1650,           /* hblank end   */ \
+               1390,           /* hsync start  */ \
+               1430,           /* hsync end    */ \
+               750,            /* vtotal       */ \
+               720,            /* vblank start */ \
+               750,            /* vblank end   */ \
+               725,            /* vsync start  */ \
+               730             /* vsync end    */
+
+#define TIMING_1280x720p5994_60_FP2 \
+               1280,           /* width        */ \
+               720,            /* height       */ \
+               OTM_HDMI_REFRESH_60, /* refresh rate */ \
+               148500,         /* clock        */ \
+               1650,           /* htotal       */ \
+               1280,           /* hblank start */ \
+               1650,           /* hblank end   */ \
+               1390,           /* hsync start  */ \
+               1430,           /* hsync end    */ \
+               1500,           /* vtotal       */ \
+               1470,           /* vblank start */ \
+               1500,           /* vblank end   */ \
+               1475,           /* vsync start  */ \
+               1480            /* vsync end    */
+
+#define TIMING_1280x720p5994_60_FSEQ \
+               1280,           /* width        */ \
+               720,            /* height       */ \
+               OTM_HDMI_REFRESH_60, /* refresh rate */ \
+               148500,  /* clock       */ \
+               1650,           /* htotal       */ \
+               1280,           /* hblank start */ \
+               1650,           /* hblank end   */ \
+               1390,           /* hsync start  */ \
+               1430,           /* hsync end    */ \
+               750,            /* vtotal       */ \
+               720,            /* vblank start */ \
+               750,            /* vblank end   */ \
+               725,            /* vsync start  */ \
+               730             /* vsync end    */
+
+/*-----------------------------------------------------------------------------
+                       1080I TIMINGS
+-----------------------------------------------------------------------------*/
+#define TIMING_1920x1080i50 \
+               1920,           /* width        */ \
+               540,            /* height       */ \
+               OTM_HDMI_REFRESH_50, /* refresh rate */ \
+               74250,          /* clock        */ \
+               2640,           /* htotal       */ \
+               1920,           /* hblank start */ \
+               2640,           /* hblank end   */ \
+               2448,           /* hsync start  */ \
+               2492,           /* hsync end    */ \
+               562,            /* vtotal       */ \
+               540,            /* vblank start */ \
+               562,            /* vblank end   */ \
+               542,            /* vsync start  */ \
+               547             /* vsync end    */
+
+#define TIMING_1920x1080i50_FP \
+               1920,           /* width        */ \
+               540,            /* height       */ \
+               OTM_HDMI_REFRESH_50, /* refresh rate */ \
+               148500,         /* clock        */ \
+               2640,           /* htotal       */ \
+               1920,           /* hblank start */ \
+               2640,           /* hblank end   */ \
+               2448,           /* hsync start  */ \
+               2492,           /* hsync end    */ \
+               562,            /* vtotal       */ \
+               540,            /* vblank start */ \
+               562,            /* vblank end   */ \
+               542,            /* vsync start  */ \
+               547             /* vsync end    */
+
+#define TIMING_1920x1080i5994_60 \
+               1920,           /* width        */ \
+               540,            /* height       */ \
+               OTM_HDMI_REFRESH_60, /* refresh rate */ \
+               74250,          /* clock        */ \
+               2200,           /* htotal       */ \
+               1920,           /* hblank start */ \
+               2200,           /* hblank end   */ \
+               2008,           /* hsync start  */ \
+               2052,           /* hsync end    */ \
+               562,            /* vtotal       */ \
+               540,            /* vblank start */ \
+               562,            /* vblank end   */ \
+               542,            /* vsync start  */ \
+               547             /* vsync end    */
+
+#define TIMING_1920x1080i5994_60_FP \
+               1920,           /* width        */ \
+               540,            /* height       */ \
+               OTM_HDMI_REFRESH_60, /* refresh rate */ \
+               148500,         /* clock        */ \
+               2200,           /* htotal       */ \
+               1920,           /* hblank start */ \
+               2200,           /* hblank end   */ \
+               2008,           /* hsync start  */ \
+               2052,           /* hsync end    */ \
+               562,            /* vtotal       */ \
+               540,            /* vblank start */ \
+               562,            /* vblank end   */ \
+               542,            /* vsync start  */ \
+               547             /* vsync end    */
+
+/*-----------------------------------------------------------------------------
+                       1080P TIMINGS
+-----------------------------------------------------------------------------*/
+#define TIMING_1920x1080p24 \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_24,    /* refresh      */ \
+               74250,          /* clock        */ \
+               2750,           /* htotal       */ \
+               1920,           /* hblank start */ \
+               2750,           /* hblank end   */ \
+               2558,           /* hsync start  */ \
+               2602,           /* hsync end    */ \
+               1125,           /* vtotal       */ \
+               1080,           /* vblank start */ \
+               1125,           /* vblank end   */ \
+               1084,           /* vsync start  */ \
+               1089            /* vsync end    */
+
+#define TIMING_1920x1080p24_FP \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_24,    /* refresh      */ \
+               148500,  /* clock       */ \
+               2750,           /* htotal       */ \
+               1920,           /* hblank start */ \
+               2750,           /* hblank end   */ \
+               2558,           /* hsync start  */ \
+               2602,           /* hsync end    */ \
+               1125,           /* vtotal       */ \
+               1080,           /* vblank start */ \
+               1125,           /* vblank end   */ \
+               1084,           /* vsync start  */ \
+               1089            /* vsync end    */
+
+#define TIMING_1920x1080p24_FP2 \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_24,    /* refresh      */ \
+               148500,         /* clock        */ \
+               2750,           /* htotal       */ \
+               1920,           /* hblank start */ \
+               2750,           /* hblank end   */ \
+               2558,           /* hsync start  */ \
+               2602,           /* hsync end    */ \
+               2250,           /* vtotal       */ \
+               2205,           /* vblank start */ \
+               2250,           /* vblank end   */ \
+               2209,           /* vsync start  */ \
+               2214            /* vsync end    */
+
+#define TIMING_1920x1080p24_FSEQ \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_24,    /* refresh      */ \
+               148500,         /* clock        */ \
+               2750,           /* htotal       */ \
+               1920,           /* hblank start */ \
+               2750,           /* hblank end   */ \
+               2558,           /* hsync start  */ \
+               2602,           /* hsync end    */ \
+               1125,           /* vtotal       */ \
+               1080,           /* vblank start */ \
+               1125,           /* vblank end   */ \
+               1084,           /* vsync start  */ \
+               1089            /* vsync end    */
+
+#define TIMING_1920x1080p25 \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_25,    /* refresh      */ \
+               74250,          /* clock        */ \
+               2640,           /* htotal       */ \
+               1920,           /* hblank start */ \
+               2640,           /* hblank end   */ \
+               2448,           /* hsync start  */ \
+               2492,           /* hsync end    */ \
+               1125,           /* vtotal       */ \
+               1080,           /* vblank start */ \
+               1125,           /* vblank end   */ \
+               1084,           /* vsync start  */ \
+               1089            /* vsync end    */
+
+#define TIMING_1920x1080p30 \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_30,    /* refresh      */ \
+               74250,          /* clock        */ \
+               2200,           /* htotal       */ \
+               1920,           /* hblank start */ \
+               2200,           /* hblank end   */ \
+               2008,           /* hsync start  */ \
+               2052,           /* hsync end    */ \
+               1125,           /* vtotal       */ \
+               1080,           /* vblank start */ \
+               1125,           /* vblank end   */ \
+               1084,           /* vsync start  */ \
+               1089            /* vsync end    */
+
+#define TIMING_1920x1080p30_FP \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_30,    /* refresh      */ \
+               148500,  /* clock       */ \
+               2200,           /* htotal       */ \
+               1920,           /* hblank start */ \
+               2200,           /* hblank end   */ \
+               2008,           /* hsync start  */ \
+               2052,           /* hsync end    */ \
+               1125,           /* vtotal       */ \
+               1080,           /* vblank start */ \
+               1125,           /* vblank end   */ \
+               1084,           /* vsync start  */ \
+               1089            /* vsync end    */
+
+#define TIMING_1920x1080p30_FP2 \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_30,    /* refresh      */ \
+               148500,         /* clock        */ \
+               2200,           /* htotal       */ \
+               1920,           /* hblank start */ \
+               2200,           /* hblank end   */ \
+               2008,           /* hsync start  */ \
+               2052,           /* hsync end    */ \
+               2250,           /* vtotal       */ \
+               2205,           /* vblank start */ \
+               2250,           /* vblank end   */ \
+               2209,           /* vsync start  */ \
+               2214            /* vsync end    */
+
+#define TIMING_1920x1080p48 \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_48,    /* refresh      */ \
+               148500,         /* clock        */ \
+               2750,           /* htotal       */ \
+               1920,           /* hblank start */ \
+               2750,           /* hblank end   */ \
+               2558,           /* hsync start  */ \
+               2602,           /* hsync end    */ \
+               1125,           /* vtotal       */ \
+               1080,           /* vblank start */ \
+               1125,           /* vblank end   */ \
+               1084,           /* vsync start  */ \
+               1089            /* vsync end    */
+
+#define TIMING_1920x1080p50 \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_50,    /* refresh      */ \
+               148500,         /* clock        */ \
+               2640,           /* htotal       */ \
+               1920,           /* hblank start */ \
+               2640,           /* hblank end   */ \
+               2448,           /* hsync start  */ \
+               2492,           /* hsync end    */ \
+               1125,           /* vtotal       */ \
+               1080,           /* vblank start */ \
+               1125,           /* blank end    */ \
+               1084,           /* vsync start  */ \
+               1089            /* vsync end    */
+
+#define TIMING_1920x1080p5994_60       \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_60,    /* refresh      */ \
+               148500,         /* clock        */ \
+               2200,           /* htotal       */ \
+               1920,           /* hblank start */ \
+               2200,           /* hblank end   */ \
+               2008,           /* hsync start  */ \
+               2052,           /* hsync end    */ \
+               1125,           /* vtotal       */ \
+               1080,           /* vblank start */ \
+               1125,           /* blank end    */ \
+               1084,           /* vsync start  */ \
+               1089            /* vsync end    */
+
+/*-----------------------------------------------------------------------------
+                       Panel TIMINGS
+-----------------------------------------------------------------------------*/
+
+#define TIMING_1920x1080p60_PANEL \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_60,    /* refresh      */ \
+               148500,         /* clock        */ \
+               2184,           /* htotal       */ \
+               1920,           /* hblank start*/ \
+               2184,           /* hblank end   */ \
+               1920 + 32,      /* hsync start */ \
+               1920 + 32 + 32, /* hsync end    */ \
+               1134,           /* vtotal       */ \
+               1080,           /* vblank start*/ \
+               1134,           /* vblank end   */ \
+               1080 + 34,      /* vsync start */ \
+               1080 + 34 + 4   /* vsync end    */
+
+#define TIMING_1920x1080p50_PANEL \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_50,    /* refresh      */ \
+               148500,         /* clock        */ \
+               2184,           /* htotal       */ \
+               1920,           /* hblank start*/ \
+               2184,           /* hblank end   */ \
+               1920 + 32,      /* hsync start */ \
+               1920 + 32 + 32, /* hsync end    */ \
+               1360,           /* vtotal       */ \
+               1080,           /* vblank start*/ \
+               1360,           /* vblank end   */ \
+               1080 + 260,     /* vsync start*/ \
+               1080 + 260 + 4  /* vsync end    */
+
+#define TIMING_1920x1080p48_PANEL \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_48,    /* refresh      */ \
+               148500,         /* clock        */ \
+               2184,           /* htotal       */ \
+               1920,           /* hblank start*/ \
+               2184,           /* hblank end   */ \
+               1920 + 32,      /* hsync start */ \
+               1920 + 32 + 32, /* hsync end    */ \
+               1417,           /* vtotal       */ \
+               1080,           /* vblank start*/ \
+               1417,           /* vblank end   */ \
+               1080 + 317,     /* vsync start */ \
+               1080 + 317 + 4  /* vsync end    */
+
+#define TIMING_1920x1080p30_PANEL_FS \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_30,    /* refresh      */ \
+               148500,         /* clock        */ \
+               2184,           /* htotal       */ \
+               1920,           /* hblank start*/ \
+               2184,           /* hblank end   */ \
+               1920 + 32,      /* hsync start */ \
+               1920 + 32 + 32, /* hsync end    */ \
+               1134,           /* vtotal       */ \
+               1080,           /* vblank start*/ \
+               1134,           /* vblank end   */ \
+               1080 + 34,      /* vsync start */ \
+               1080 + 34 + 4   /* vsync end    */
+
+#define TIMING_1920x1080p25_PANEL_FS \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_25,    /* refresh      */ \
+               148500,         /* clock        */ \
+               2184,           /* htotal       */ \
+               1920,           /* hblank start*/ \
+               2184,           /* hblank end   */ \
+               1920 + 32,      /* hsync start */ \
+               1920 + 32 + 32, /* hsync end    */ \
+               1360,           /* vtotal       */ \
+               1080,           /* vblank start*/ \
+               1360,           /* vblank end   */ \
+               1080 + 260,     /* vsync start*/ \
+               1080 + 260 + 4  /* vsync end    */
+
+#define TIMING_1920x1080p24_PANEL_FS \
+               1920,           /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_24,    /* refresh      */ \
+               148500,         /* clock        */ \
+               2184,           /* htotal       */ \
+               1920,           /* hblank start*/ \
+               2184,           /* hblank end   */ \
+               1920 + 32,      /* hsync start */ \
+               1920 + 32 + 32, /* hsync end    */ \
+               1417,           /* vtotal       */ \
+               1080,           /* vblank start*/ \
+               1417,           /* vblank end   */ \
+               1080 + 317,     /* vsync start */ \
+               1080 + 317 + 4  /* vsync end    */
+
+#define TIMING_960x1080p60_PANEL_FS \
+               960,            /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_60,    /* refresh      */ \
+               148500,         /* clock        */ \
+               1092,           /* htotal       */ \
+               960,            /* hblank start*/ \
+               1092,           /* hblank end   */ \
+               960 + 24,       /* hsync start */ \
+               960 + 24 + 32,  /* hsync end    */ \
+               1134,           /* vtotal       */ \
+               1080,           /* vblank start*/ \
+               1134,           /* vblank end   */ \
+               1080 + 34,      /* vsync start */ \
+               1080 + 34 + 4   /* vsync end    */
+
+#define TIMING_960x1080p50_PANEL_FS \
+               960,            /* width        */ \
+               1080,           /* height       */ \
+               OTM_HDMI_REFRESH_50,    /* refresh      */ \
+               148500,         /* clock        */ \
+               1092,           /* htotal       */ \
+               960,            /* hblank start*/ \
+               1092,           /* hblank end   */ \
+               960 + 24,       /* hsync start */ \
+               960 + 24 + 32,  /* hsync end    */ \
+               1360,           /* vtotal       */ \
+               1080,           /* vblank start*/ \
+               1360,           /* vblank end   */ \
+               1080 + 260,     /* vsync start */ \
+               1080 + 260 + 4  /* vsync end    */
+
+#define TIMING_1920x540p60_PANEL_FS \
+               1920,           /* width        */ \
+               540,            /* height       */ \
+               OTM_HDMI_REFRESH_60,    /* refresh      */ \
+               148500,         /* clock        */ \
+               2184,           /* htotal       */ \
+               1920,           /* hblank start*/ \
+               2184,           /* hblank end   */ \
+               1920 + 32,      /* hsync start */ \
+               1920 + 32 + 32, /* hsync end    */ \
+               567,            /* vtotal       */ \
+               540,            /* vblank start*/ \
+               567,            /* vblank end   */ \
+               540 + 17,       /* vsync start */ \
+               540 + 17 + 4    /* vsync end    */
+
+#define TIMING_1920x540p50_PANEL_FS \
+               1920,           /* width        */ \
+               540,            /* height       */ \
+               OTM_HDMI_REFRESH_50,    /* refresh      */ \
+               148500,         /* clock        */ \
+               2184,           /* htotal       */ \
+               1920,           /* hblank start*/ \
+               2184,           /* hblank end   */ \
+               1920 + 32,      /* hsync start */ \
+               1920 + 32 + 32, /* hsync end    */ \
+               680,            /* vtotal       */ \
+               540,            /* vblank start*/ \
+               680,            /* vblank end   */ \
+               540 + 130,      /* vsync start */ \
+               540 + 130 + 4   /* vsync end    */
+
+#define TIMING_1280x720p60_PANEL_FS \
+               1280,           /* width        */ \
+               720,            /* height       */ \
+               OTM_HDMI_REFRESH_60,    /* refresh      */ \
+               148500,         /* clock        */ \
+               1650,           /* htotal       */ \
+               1280,           /* hblank start*/ \
+               1650,           /* hblank end   */ \
+               1390,           /* hsync start */ \
+               1422,           /* hsync end    */ \
+               750,            /* vtotal       */ \
+               720,            /* vblank start*/ \
+               750,            /* vblank end   */ \
+               735,            /* vsync start */ \
+               739             /* vsync end    */
+
+#define TIMING_1280x720p50_PANEL_FS \
+               1280,           /* width        */ \
+               720,            /* height       */ \
+               OTM_HDMI_REFRESH_50,    /* refresh      */ \
+               148500,         /* clock        */ \
+               1650,           /* htotal       */ \
+               1280,           /* hblank start*/ \
+               1650,           /* hblank end   */ \
+               1280 + 110,     /* hsync start */ \
+               1280 + 110 + 32,/* hsync end    */ \
+               900,            /* vtotal       */ \
+               720,            /* vblank start*/ \
+               900,            /* vblank end   */ \
+               720 + 165,      /* vsync start */ \
+               720 + 165 + 4   /* vsync end    */
+
+
+const otm_hdmi_timing_t MODE_640x480p5994_60 = {
+       TIMING_640x480p5994_60,
+       0,                      /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       1                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_720x480p5994_60 = {
+       TIMING_720x480p5994_60,
+       0,                      /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       2                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_720x480p5994_60__16by9 = {
+       TIMING_720x480p5994_60,
+       PD_AR_16_BY_9,          /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       3                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1280x720p5994_60 = {
+       TIMING_1280x720p5994_60,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                               /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       4                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080i5994_60 = {
+       TIMING_1920x1080i5994_60,
+       PD_SCAN_INTERLACE | PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                               /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       5                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080i5994_60__FP = {
+       TIMING_1920x1080i5994_60_FP,
+       PD_SCAN_INTERLACE | PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                       /* flags */
+       OTM_HDMI_STEREO_FRAME_PACKING,  /* stereo_type */
+       5                               /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_720_1440x480i5994_60 = {
+       TIMING_720_1440x480i5994_60,
+       PD_SCAN_INTERLACE,      /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       6                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_720_1440x480i5994_60__16by9 = {
+       TIMING_720_1440x480i5994_60,
+       PD_SCAN_INTERLACE | PD_AR_16_BY_9,
+                               /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       7                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p5994_60 = {
+       TIMING_1920x1080p5994_60,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                               /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       16                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_720x576p50 = {
+       TIMING_720x576p50,
+       0,                      /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       17                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_720x576p50__16by9 = {
+       TIMING_720x576p50,
+       PD_AR_16_BY_9,          /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       18                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1280x720p50 = {
+       TIMING_1280x720p50,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                               /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       19                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080i50 = {
+       TIMING_1920x1080i50,
+       PD_SCAN_INTERLACE | PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                               /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       20                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080i50__FP = {
+       TIMING_1920x1080i50_FP,
+       PD_SCAN_INTERLACE | PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                       /* flags */
+       OTM_HDMI_STEREO_FRAME_PACKING,  /* stereo_type */
+       20                              /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_720_1440x576i50 = {
+       TIMING_720_1440x576i50,
+       PD_SCAN_INTERLACE,      /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       21                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_720_1440x576i50__16by9 = {
+       TIMING_720_1440x576i50,
+       PD_SCAN_INTERLACE | PD_AR_16_BY_9,
+                               /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       22                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p50 = {
+       TIMING_1920x1080p50,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                               /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       31                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p24 = {
+       TIMING_1920x1080p24,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                               /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       32                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p25 = {
+       TIMING_1920x1080p25,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                               /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       33                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p30 = {
+       TIMING_1920x1080p30,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                               /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       34                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p30__FP2 = {
+       TIMING_1920x1080p30_FP2,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                       /* flags */
+       OTM_HDMI_STEREO_FRAME_PACKING_2,/* stereo_type */
+       34                              /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p30__FP = {
+       TIMING_1920x1080p30_FP,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                       /* flags */
+       OTM_HDMI_STEREO_FRAME_PACKING,  /* stereo_type */
+       34                              /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p30__TBH2 = {
+       TIMING_1920x1080p30,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                               /* flags */
+       OTM_HDMI_STEREO_TOP_BOTTOM_HALF_2,      /* stereo_type */
+       34                                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p48 = {
+       TIMING_1920x1080p48,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                               /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       32                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p24__FP2 = {
+       TIMING_1920x1080p24_FP2,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                       /* flags */
+       OTM_HDMI_STEREO_FRAME_PACKING_2,/* stereo_type */
+       32                              /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p24__FP = {
+       TIMING_1920x1080p24_FP,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                       /* flags */
+       OTM_HDMI_STEREO_FRAME_PACKING,  /* stereo_type */
+       32                              /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1280x720p5994_60__FP2 = {
+       TIMING_1280x720p5994_60_FP2,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                       /* flags */
+       OTM_HDMI_STEREO_FRAME_PACKING_2,/* stereo_type */
+       4                               /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1280x720p5994_60__FP = {
+       TIMING_1280x720p5994_60_FP,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                       /* flags */
+       OTM_HDMI_STEREO_FRAME_PACKING,  /* stereo_type */
+       4                               /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1280x720p50__FP2 = {
+       TIMING_1280x720p50_FP2,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                       /* flags */
+       OTM_HDMI_STEREO_FRAME_PACKING_2,/* stereo_type */
+       19                              /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1280x720p50__FP = {
+       TIMING_1280x720p50_FP,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                       /* flags */
+       OTM_HDMI_STEREO_FRAME_PACKING,  /* stereo_type */
+       19                              /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1280x720p5994_60__SBSH2 = {
+       TIMING_1280x720p5994_60,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                               /* flags */
+       OTM_HDMI_STEREO_SIDE_BY_SIDE_HALF_2,    /* stereo_type */
+       4                                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1280x720p50__SBSH2 = {
+       TIMING_1280x720p50,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                               /* flags */
+       OTM_HDMI_STEREO_SIDE_BY_SIDE_HALF_2,    /* stereo_type */
+       19                                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080i5994_60__SBSH2 = {
+       TIMING_1920x1080i5994_60,
+       PD_SCAN_INTERLACE | PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                               /* flags */
+       OTM_HDMI_STEREO_SIDE_BY_SIDE_HALF_2,    /* stereo_type */
+       5                                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080i50__SBSH2 = {
+       TIMING_1920x1080i50,
+       PD_SCAN_INTERLACE | PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                               /* flags */
+       OTM_HDMI_STEREO_SIDE_BY_SIDE_HALF_2,    /* stereo_type */
+       20                                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p5994_60__SBSH2 = {
+       TIMING_1920x1080p5994_60,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                               /* flags */
+       OTM_HDMI_STEREO_SIDE_BY_SIDE_HALF_2,    /* stereo_type */
+       16                                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p50__SBSH2 = {
+       TIMING_1920x1080p50,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                               /* flags */
+       OTM_HDMI_STEREO_SIDE_BY_SIDE_HALF_2,    /* stereo_type */
+       31                                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p24__SBSH2 = {
+       TIMING_1920x1080p24,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                               /* flags */
+       OTM_HDMI_STEREO_SIDE_BY_SIDE_HALF_2,    /* stereo_type */
+       32                                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1280x720p5994_60__TBH2 = {
+       TIMING_1280x720p5994_60,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                               /* flags */
+       OTM_HDMI_STEREO_TOP_BOTTOM_HALF_2,      /* stereo_type */
+       4                                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1280x720p50__TBH2 = {
+       TIMING_1280x720p50,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                               /* flags */
+       OTM_HDMI_STEREO_TOP_BOTTOM_HALF_2,      /* stereo_type */
+       19                                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p5994_60__TBH2 = {
+       TIMING_1920x1080p5994_60,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                               /* flags */
+       OTM_HDMI_STEREO_TOP_BOTTOM_HALF_2,      /* stereo_type */
+       16                                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p50__TBH2 = {
+       TIMING_1920x1080p50,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                               /* flags */
+       OTM_HDMI_STEREO_TOP_BOTTOM_HALF_2,      /* stereo_type */
+       31                                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p24__TBH2 = {
+       TIMING_1920x1080p24,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH,
+                                               /* flags */
+       OTM_HDMI_STEREO_TOP_BOTTOM_HALF_2,      /* stereo_type */
+       32                                      /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1280x720p60__PANEL_FS = {
+       TIMING_1280x720p60_PANEL_FS,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH | PD_DTV_MODE,
+                                               /* flags */
+       OTM_HDMI_STEREO_FRAME_SEQUENTIAL,       /* stereo_type */
+       0                                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1280x720p50__PANEL_FS = {
+       TIMING_1280x720p50_PANEL_FS,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH | PD_DTV_MODE,
+                                               /* flags */
+       OTM_HDMI_STEREO_FRAME_SEQUENTIAL,       /* stereo_type */
+       0                                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x540p60__PANEL_FS = {
+       TIMING_1920x540p60_PANEL_FS,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH | PD_DTV_MODE,
+                                               /* flags */
+       OTM_HDMI_STEREO_FRAME_SEQUENTIAL,       /* stereo_type */
+       0                                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x540p50__PANEL_FS = {
+       TIMING_1920x540p50_PANEL_FS,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH | PD_DTV_MODE,
+                                               /* flags */
+       OTM_HDMI_STEREO_FRAME_SEQUENTIAL,       /* stereo_type */
+       0                                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_920x1080p60__PANEL_FS = {
+       TIMING_960x1080p60_PANEL_FS,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH | PD_DTV_MODE,
+                                               /* flags */
+       OTM_HDMI_STEREO_FRAME_SEQUENTIAL,       /* stereo_type */
+       0                                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_920x1080p50__PANEL_FS = {
+       TIMING_960x1080p50_PANEL_FS,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH | PD_DTV_MODE,
+                                               /* flags */
+       OTM_HDMI_STEREO_FRAME_SEQUENTIAL,       /* stereo_type */
+       0                                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p30__PANEL_FS = {
+       TIMING_1920x1080p30_PANEL_FS,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH | PD_DTV_MODE,
+                                               /* flags */
+       OTM_HDMI_STEREO_FRAME_SEQUENTIAL,       /* stereo_type */
+       0                                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p25__PANEL_FS = {
+       TIMING_1920x1080p25_PANEL_FS,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH | PD_DTV_MODE,
+                                               /* flags */
+       OTM_HDMI_STEREO_FRAME_SEQUENTIAL,       /* stereo_type */
+       0                                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p24__PANEL_FS = {
+       TIMING_1920x1080p24_PANEL_FS,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH | PD_DTV_MODE,
+                                               /* flags */
+       OTM_HDMI_STEREO_FRAME_SEQUENTIAL,       /* stereo_type */
+       0                                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p60__PANEL = {
+       TIMING_1920x1080p60_PANEL,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH | PD_DTV_MODE,
+                               /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       0                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p50__PANEL = {
+       TIMING_1920x1080p50_PANEL,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH | PD_DTV_MODE,
+                               /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       0                       /* Metadata VIC */
+};
+
+const otm_hdmi_timing_t MODE_1920x1080p48__PANEL = {
+       TIMING_1920x1080p48_PANEL,
+       PD_AR_16_BY_9 | PD_HSYNC_HIGH | PD_VSYNC_HIGH | PD_DTV_MODE,
+                               /* flags */
+       OTM_HDMI_STEREO_NONE,   /* stereo_type */
+       0                       /* Metadata VIC */
+};
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/common/otm_hdmi.c b/drivers/staging/mrst/drv/otm_hdmi/pil/common/otm_hdmi.c
new file mode 100644 (file)
index 0000000..90dc331
--- /dev/null
@@ -0,0 +1,2235 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+       Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+       Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+
+#include <linux/time.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include "otm_hdmi.h"
+#include "ipil_hdmi.h"
+
+#include "hdmi_internal.h"
+#include "hdmi_timings.h"
+#ifdef OTM_HDMI_HDCP_ENABLE
+#include "hdcp_api.h"
+#endif
+#include "edid.h"
+#include "ps_hdmi.h"
+#include "ips_hdmi.h"
+#include "infoframes_api.h"
+
+/* TODO: Leave it here or move to some .h? */
+#define OTM_HDMI_NAME "OTM HDMI"
+
+/**
+ * Table of attributes
+ */
+otm_hdmi_attribute_t otm_hdmi_attributes_table
+               [OTM_HDMI_MAX_SUPPORTED_ATTRIBUTES];
+
+/* Placeholder for all TX supported modes */
+static const otm_hdmi_timing_t *g_video_modes[MAX_TIMINGS];
+/* Placeholder for all TX supported modes per CEA 861E spec used by EDID parser
+ */
+static const otm_hdmi_timing_t *g_video_modes_ref[MAX_TIMINGS];
+static otm_hdmi_ret_t otm_hdmi_attr_set_validate(otm_hdmi_attribute_id_t id,
+                                                       void *value);
+static otm_hdmi_ret_t otm_hdmi_attr_get_validate(otm_hdmi_attribute_id_t id);
+
+static otm_hdmi_ret_t __pd_attr_declare(otm_hdmi_attribute_t *table,
+                               otm_hdmi_attribute_id_t id,
+                               otm_hdmi_attribute_type_t type,
+                               otm_hdmi_attribute_flag_t flags,
+                               char *name,
+                               void *value,
+                               unsigned int min,
+                               unsigned int max);
+
+static unsigned int g_gpio = GPIO_MIN;
+static unsigned int g_dtv;
+static unsigned int g_dc = 1;
+
+#define EDID_SIGNATURE 0x00FFFFFFFFFFFF00ull
+
+static hdmi_context_t *g_context;
+
+/* This table preserves the special timings for DTV models */
+static const otm_hdmi_timing_t *static_dtv_modes[] = {
+       &MODE_1920x1080p60__PANEL,
+       &MODE_1920x1080p50__PANEL,
+       &MODE_1920x1080p48__PANEL,
+       &MODE_1280x720p60__PANEL_FS,
+       &MODE_1280x720p50__PANEL_FS,
+       &MODE_1920x540p60__PANEL_FS,
+       &MODE_1920x540p50__PANEL_FS,
+       &MODE_920x1080p60__PANEL_FS,
+       &MODE_920x1080p50__PANEL_FS,
+       &MODE_1920x1080p30__PANEL_FS,
+       &MODE_1920x1080p25__PANEL_FS,
+       &MODE_1920x1080p24__PANEL_FS,
+};
+
+/* This table contains list of audio timings supported by Intel CE Media
+ * Processors and used in the situations when EDID is not available
+ *
+ * Note: Do *NOT* add declaration WMA in here as we dont have approval for that
+ */
+static otm_hdmi_audio_cap_t static_audio_modes[] = {
+       DECLARE_AUDIO_CAP(OTM_HDMI_AUDIO_FORMAT_PCM, 8, ALL_SF, ALL_SS),
+       DECLARE_AUDIO_CAP(OTM_HDMI_AUDIO_FORMAT_AC3, 8, ALL_SF, 640 / 8),
+       DECLARE_AUDIO_CAP(OTM_HDMI_AUDIO_FORMAT_DTS, 8, ALL_SF, 1536 / 8),
+       DECLARE_AUDIO_CAP(OTM_HDMI_AUDIO_FORMAT_DDP, 8, ALL_SF, 0),
+       DECLARE_AUDIO_CAP(OTM_HDMI_AUDIO_FORMAT_DTSHD, 8, ALL_SF, 0),
+       DECLARE_AUDIO_CAP(OTM_HDMI_AUDIO_FORMAT_MLP, 8, ALL_SF, 0),
+};
+
+static otm_hdmi_ret_t __program_clocks(hdmi_context_t *ctx, unsigned int dclk)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       return rc;
+}
+
+/*
+ * Wrapper over printing to both console and SVEN. Note that Both underlying
+ * routines accept frame stack pointer
+ */
+static int __vprintf(const char *fmt, ...)
+{
+       int rc = 0;
+       va_list argp;
+
+       /* Log on console only if debug is on */
+       if (PD_ATTR_UINT(ATTRS[OTM_HDMI_ATTR_ID_DEBUG]) >= PD_LOG_LEVEL_ERROR) {
+               va_start(argp, fmt);
+               rc = vprintk(fmt, argp);
+               va_end(argp);
+       }
+       return rc;
+}
+
+static void __hdmi_report_edid(hdmi_context_t *ctx, edid_info_t *edid)
+{
+       int i = 0;
+
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "----------------------\n");
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "Name     : %s\n", edid->product_name);
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "Year     : %d\n", edid->product_year);
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "SN       : %d\n", edid->product_sn);
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "Type     : %s\n",
+                       edid->hdmi ? "HDMI" : "DVI");
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "YCbCr444 : %s\n",
+                       edid->ycbcr444 ? "Y" : "N");
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "YCbCr422 : %s\n",
+                       edid->ycbcr422 ? "Y" : "N");
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "30 bpp   : %s\n",
+                       edid->dc_30 ? "Y" : "N");
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "36 bpp   : %s\n",
+                       edid->dc_36 ? "Y" : "N");
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "48 bpp   : %s\n",
+                       edid->dc_48 ? "Y" : "N");
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "DC_YUV   : %s\n",
+                       edid->dc_y444 ? "Y" : "N");
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "Max CLK  : %d\n",
+                       edid->max_tmds_clock);
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "Lip sync : %s\n",
+                       edid->latency_present ? "Y" : "N");
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "ILip sync: %s\n",
+                       edid->latency_int_present ? "Y" : "N");
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "Vid lat  : %d\n",
+                       edid->latency_video);
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "Aud lat  : %d\n",
+                       edid->latency_audio);
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "IVid lat : %d\n",
+                       edid->latency_video_interlaced);
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "IAud lat : %d\n",
+                       edid->latency_audio_interlaced);
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "HDMI VID : %s\n",
+                       edid->hdmi_video_present ? "Y" : "N");
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "HDMI 3D  : %s\n",
+                       edid->enabled_3d ? "Y" : "N");
+
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "SPA      : %d.%d.%d.%d\n",
+                 (edid->spa & 0xF000) >> 12,
+                 (edid->spa & 0x0F00) >> 8,
+                 (edid->spa & 0x00F0) >> 4, (edid->spa & 0x000F) >> 0);
+
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "Supported timings [%d]:\n",
+                 edid->num_timings);
+
+       for (i = 0; i < edid->num_timings; i++)
+               print_pd_timing(&edid->timings[i], edid->order[i], __vprintf);
+
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "Audio capabilities:\n");
+       for (i = 0; i < edid->num_caps; i++)
+               print_audio_capability(&edid->audio_caps[i], __vprintf);
+
+       print_speaker_layout(edid->speaker_map, __vprintf);
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "----------------------\n");
+}
+
+static otm_hdmi_ret_t __hdmi_edid_override(hdmi_context_t *ctx,
+                               edid_info_t *edid,
+                               bool safe)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       unsigned int i, n = 0;
+       bool hdmi;
+       bool dc_30, dc_36;
+       const otm_hdmi_timing_t **modes = NULL;
+       bool hdcp = PD_ATTR_BOOL(ATTRS[OTM_HDMI_ATTR_ID_HDCP]);
+       unsigned int n_modes_dtv = NUM_ENTRIES_IN(static_dtv_modes);
+
+       /* Verify pointers */
+       if (!(edid)) {
+               rc = OTM_HDMI_ERR_INTERNAL;
+               goto exit;
+       }
+       /* Save device type and DC caps */
+       hdmi = !ctx->dtv && (safe ? edid->hdmi : true);
+       dc_30 = hdmi && edid->dc_30;
+       dc_36 = hdmi && edid->dc_36;
+
+       /* Clear EDID */
+       memset(edid, 0, sizeof(edid_info_t));
+
+       /* Set device type */
+       edid->hdmi = hdmi;
+
+       /* Pick caps table based on whether we are HDMI TX or DTV */
+       modes = ctx->dtv ? static_dtv_modes : g_video_modes;
+       n = ctx->dtv ? n_modes_dtv : ctx->n_modes_tx;
+
+       /* Add all supported video modes */
+       for (i = edid->num_timings = 0; i < n; i++) {
+               edid->timings[edid->num_timings++] = *modes[i];
+
+               /* Do NOT advertise 3D modes in DVI mode unless we are in DTV
+                * mode which means always use DTV static table
+                */
+               if (!ctx->dtv && !hdmi &&
+                       modes[i]->stereo_type != OTM_HDMI_STEREO_NONE) {
+                       edid->num_timings--;
+               }
+       }
+
+       /* Set HDCP based on DTV indicator */
+       PD_ATTR_BOOL(ATTRS[OTM_HDMI_ATTR_ID_HDCP]) =
+                               ctx->dtv ? false : hdcp;
+
+       /* Dont bother with HDMI caps if we are in DVI mode */
+       if (!(hdmi))
+               goto exit;
+
+       /* Add all supported audio modes */
+       edid->num_caps = NUM_ENTRIES_IN(static_audio_modes);
+       for (i = 0; i < edid->num_caps; i++)
+               edid->audio_caps[i] = static_audio_modes[i];
+
+       /* Enable all possible speaker allocation maps */
+       edid->speaker_map |= 0x3ff;
+
+       /* Indicate support of deep color and YCbCr output */
+       edid->ycbcr444 = true;
+       edid->ycbcr422 = true;
+       edid->dc_30 = safe ? dc_30 : true;
+       edid->dc_36 = safe ? dc_36 : true;
+
+exit:
+       return rc;
+}
+
+/**
+ *     otm_hdmi_edid_parse() - fill capability table
+ *     @ctx:      hdmi context
+ *     @use_edid: True or False
+ *
+ *     This routine files capability table.
+ *
+ *     Returns - check otm_hdmi_ret_t
+ */
+otm_hdmi_ret_t otm_hdmi_edid_parse(void *context, otm_hdmi_use_edid_t use_edid)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       i2c_read_t edid_foo = ps_hdmi_i2c_edid_read;
+       bool cable = PD_ATTR_BOOL(ATTRS[OTM_HDMI_ATTR_ID_CABLE_STATUS]);
+       edid_info_t *edid;
+       unsigned int i;
+       hdmi_context_t *ctx = (hdmi_context_t *)context;
+
+       /* Verify pointers */
+       if (!ctx) {
+               rc = OTM_HDMI_ERR_INTERNAL;
+               goto exit;
+       }
+       /* Init locals */
+       edid = &ctx->edid_int;
+
+       /* Begin EDID update protection */
+       mutex_lock(&ctx->modes_sema);
+
+       /* Clear EDID */
+       memset(edid, 0, sizeof(edid_info_t));
+
+       /* Setup reference table for parsing */
+       edid->num_ref_timings = ctx->n_modes_ref;
+       edid->ref_timings = g_video_modes_ref;
+
+       /* DTV mode will use static DTV timings directly */
+       if (ctx->dtv)
+               goto edid_override;
+
+       switch (use_edid) {
+       case OTM_HDMI_USE_EDID_REAL:
+               /* Try reading EDID. If reading failed pick overriding strategy
+                * based on cable status
+               */
+               rc = edid_parse(edid, edid_foo, ctx, false);
+               if (rc != OTM_HDMI_SUCCESS) {
+                       pr_debug("Failed to read EDID info\n");
+                       use_edid = cable ? OTM_HDMI_USE_EDID_SAFE :
+                               OTM_HDMI_USE_EDID_NONE;
+               }
+               break;
+       case OTM_HDMI_USE_EDID_SAFE:
+               /* In safe mode we still need real EDID */
+               edid_parse(edid, edid_foo, ctx, false);
+               break;
+       case OTM_HDMI_USE_EDID_NONE:
+               /* In full override mode we dont care of real EDID
+                * so do nothing
+                */
+               break;
+       default:
+               rc = OTM_HDMI_ERR_FAILED;
+               goto exit;
+       }
+
+       /* Dont bother with static timings if we are using real EDID */
+       if (use_edid == OTM_HDMI_USE_EDID_REAL)
+               goto twin_caps;
+
+edid_override:
+       /* Use static timings */
+       __hdmi_edid_override(ctx, edid, use_edid == OTM_HDMI_USE_EDID_SAFE);
+
+       /* Insertion of twin entries below is done right in the parsed table of
+        * modes without knowledge of its maximum size. Be extra careful about
+        * it and check that MAX_TIMINGS is big enough; This needs to be fixed
+        * in long run
+        */
+twin_caps:
+       /* Insert 59.94 entries */
+       hdmi_timing_add_twin_entries(edid, OTM_HDMI_REFRESH_60,
+                                       OTM_HDMI_REFRESH_59_94);
+
+       /* Insert 29.97 entries */
+       hdmi_timing_add_twin_entries(edid, OTM_HDMI_REFRESH_30,
+                                       OTM_HDMI_REFRESH_29_97);
+
+       /* Insert 23.98 entries */
+       hdmi_timing_add_twin_entries(edid, OTM_HDMI_REFRESH_24,
+                                       OTM_HDMI_REFRESH_23_98);
+
+       /* Insert 47.96 entries */
+       hdmi_timing_add_twin_entries(edid, OTM_HDMI_REFRESH_48,
+                                       OTM_HDMI_REFRESH_47_96);
+
+       /* Adjust received timings */
+       for (i = 0; i < edid->num_timings; i++)
+               hdmi_timing_edid_to_vdc(&edid->timings[i]);
+
+       /* Print warning message in case there are no timings */
+       if (ctx->edid_int.num_timings == 0) {
+               PD_LOG_ERROR
+                   ("----------------- WARNING -----------------------\n");
+               PD_LOG_ERROR
+                   ("-- TV timings are not available           --\n");
+               PD_LOG_ERROR
+                   ("-- To resolve this switch to static TV timings --\n");
+       }
+       /* Update EDID availability indicator */
+       PD_ATTR_UINT(ATTRS[OTM_HDMI_ATTR_ID_USE_EDID]) = use_edid;
+
+       /* End EDID update protection */
+       mutex_unlock(&ctx->modes_sema);
+
+exit:
+       return rc;
+}
+
+/**
+ *  otm_hdmi_timing_from_cea_modes() - get timings for cea modes
+ *     @buffer: the extension block buffer
+ *     @timings: the result CEA timings extacted from the buffer
+ *
+ *     Returns - the number of modes in the timings
+ */
+int otm_hdmi_timing_from_cea_modes(unsigned char *buffer,
+                                  otm_hdmi_timing_t *timings)
+{
+       edid_info_t *edid  = NULL;
+
+       if (buffer == NULL)
+               return 0;
+
+       if (timings == NULL)
+               return 0;
+
+       if (g_context == NULL)
+               return 0;
+
+       edid = &g_context->edid_int;
+       if (edid == NULL)
+               return 0;
+
+       edid->num_ref_timings = g_context->n_modes_ref;
+       edid->ref_timings = g_video_modes_ref;
+
+       return edid_parse_pd_timing_from_cea_block(edid, buffer, timings);
+}
+
+/*
+ * otm_hdmi_get_mode_timings() - get timings of a mode, given:
+ * @ctx     : HDMI context
+ * @hdisplay: mode width
+ * @vdisplay: mode height
+ * @vrefresh: mode refresh rate
+ *
+ * Returns matching mode, NULL otherwise.
+ */
+otm_hdmi_timing_t *otm_hdmi_get_mode_timings(void *context,
+                                               int hdisplay,
+                                               int vdisplay,
+                                               int vrefresh)
+{
+       otm_hdmi_timing_t *mode = NULL;
+       int i, refresh_rate;
+
+       if (hdisplay < 0 || vdisplay < 0 || vrefresh < 0)
+               goto exit;
+
+       for (i = 0; i < MAX_TIMINGS; i++) {
+               mode = g_video_modes[i];
+               refresh_rate = ((mode->dclk * 1000) /
+                                       (mode->htotal * mode->vtotal));
+               if (hdisplay == mode->width &&
+                       vdisplay == mode->height &&
+                       vrefresh == refresh_rate)
+                       return mode;
+       }
+exit:
+       return NULL;
+}
+
+/* This routine fills given table with timings according to current unit version
+ * and subsequent use of table
+ */
+static int __init_tx_modes(hdmi_unit_revision_id_t unit_id,
+                          const otm_hdmi_timing_t **table,
+                          unsigned int max_size, bool reference)
+{
+       int i = 0;
+
+#define __ADD_MODE(mode)    \
+       do { \
+               if (i < max_size) \
+                       table[i++] = mode;  \
+               else {                 \
+                   i = -1;          \
+                   goto exit;    \
+               }       \
+       } while (0);
+
+       /* The following 2D modes are supported on all unit revisions */
+       __ADD_MODE(&MODE_640x480p5994_60);
+       __ADD_MODE(&MODE_720_1440x576i50);
+       __ADD_MODE(&MODE_720_1440x480i5994_60);
+       __ADD_MODE(&MODE_720x576p50);
+       __ADD_MODE(&MODE_720x480p5994_60);
+       __ADD_MODE(&MODE_1280x720p50);
+       __ADD_MODE(&MODE_1280x720p5994_60);
+       __ADD_MODE(&MODE_1920x1080i50);
+       __ADD_MODE(&MODE_1920x1080i5994_60);
+       __ADD_MODE(&MODE_1920x1080p24);
+       __ADD_MODE(&MODE_1920x1080p25);
+       __ADD_MODE(&MODE_1920x1080p30);
+       __ADD_MODE(&MODE_1920x1080p50);
+       __ADD_MODE(&MODE_1920x1080p5994_60);
+
+       /* The following 3D modes are supported on all unit revisions */
+       __ADD_MODE(&MODE_1280x720p50__SBSH2);
+       __ADD_MODE(&MODE_1280x720p5994_60__SBSH2);
+       __ADD_MODE(&MODE_1920x1080i50__SBSH2);
+       __ADD_MODE(&MODE_1920x1080i5994_60__SBSH2);
+       __ADD_MODE(&MODE_1920x1080p24__SBSH2);
+       __ADD_MODE(&MODE_1920x1080p50__SBSH2);
+       __ADD_MODE(&MODE_1920x1080p5994_60__SBSH2);
+       __ADD_MODE(&MODE_1280x720p50__TBH2);
+       __ADD_MODE(&MODE_1280x720p5994_60__TBH2);
+       __ADD_MODE(&MODE_1920x1080p24__TBH2);
+       __ADD_MODE(&MODE_1920x1080p30__TBH2);
+       __ADD_MODE(&MODE_1920x1080p50__TBH2);
+       __ADD_MODE(&MODE_1920x1080p5994_60__TBH2);
+       __ADD_MODE(&MODE_1280x720p50__FP2);
+       __ADD_MODE(&MODE_1920x1080p30__FP2);
+
+       /* The following modes are only included if the table is used as a
+        * reference set for EDID parsing
+        */
+       if (reference) {
+               __ADD_MODE(&MODE_720_1440x576i50__16by9);
+               __ADD_MODE(&MODE_720_1440x480i5994_60__16by9);
+               __ADD_MODE(&MODE_720x576p50__16by9);
+               __ADD_MODE(&MODE_720x480p5994_60__16by9);
+       }
+       /* The following mode are supported only on CE4200 B0 and further */
+       if (unit_id >= HDMI_PCI_REV_CE4200_B0) {
+               __ADD_MODE(&MODE_1280x720p50__FP);
+               __ADD_MODE(&MODE_1280x720p5994_60__FP);
+               __ADD_MODE(&MODE_1920x1080i50__FP);
+               __ADD_MODE(&MODE_1920x1080i5994_60__FP);
+               __ADD_MODE(&MODE_1920x1080p24__FP);
+               __ADD_MODE(&MODE_1920x1080p30__FP);
+       }
+#undef __ADD_MODE
+
+exit:
+       return i;
+}
+
+/**
+ *     otm_hdmi_phy_enable() - PHY power programming wrapper
+ *     @ctx:    hdmi context
+ *     @status: status
+ *
+ *     This routine is PHY power programming wrapper
+ *
+ *     Returns - check otm_hdmi_ret_t
+ */
+otm_hdmi_ret_t __hdmi_phy_enable(void *context, bool status)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       hdmi_context_t *ctx = (hdmi_context_t *)context;
+
+       bool cable = PD_ATTR_BOOL(ATTRS
+                               [OTM_HDMI_ATTR_ID_CABLE_STATUS]);
+#ifdef SOC_HDCP_ENABLE
+       bool mute = PD_ATTR_BOOL(ATTRS
+                               [OTM_HDMI_ATTR_ID_HDCP_AUTO_MUTE]);
+#endif
+       /* Safety checks */
+       if (ctx == NULL) {
+               rc = OTM_HDMI_ERR_INTERNAL;
+               goto exit;
+       }
+
+       /* Override given setting based on current mode, cable status and
+        * hot plug processing state
+        * TODO - Fix timerisset
+        */
+       status = status && ctx->mode_set
+           && cable /* && !timerisset(&ctx->phy_time) */ ;
+
+       /* It's gonna take a while for HDCP to re-authenticate after phy
+        * enabling hence mute output to prevent premium content going out
+        * unencrypted
+        */
+#ifdef SOC_HDCP_ENABLE
+       if (PD_ATTR_BOOL(ATTRS[OTM_HDMI_ATTR_ID_HDCP]) && status && mute)
+               hdmi_mute(ctx, OTM_HDMI_MUTE_VIDEO, MUTE_SOURCE_HDCP);
+#endif
+
+       pr_debug("About to call hdmi_phy_enable\n");
+       /* Program HW and update status indicator */
+
+       rc = hdmi_phy_enable(&ctx->dev, status);
+       if (rc != OTM_HDMI_SUCCESS)
+               goto exit;
+       ctx->phy_status = status;
+
+       /* Debug print */
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "PHY -> %s\n", status ? "on" : "off");
+
+exit:
+       return rc;
+}
+
+/* Enable hdmi HW device */
+static otm_hdmi_ret_t __hdmi_enable(hdmi_context_t *ctx)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+
+       /* Check context */
+       if (ctx == NULL) {
+               rc = OTM_HDMI_ERR_INTERNAL;
+               goto exit;
+       }
+
+       /* Disable PHY */
+       rc = __hdmi_phy_enable(ctx, false);
+       pr_debug("phy_enable returned with %d\n", rc);
+
+#ifdef OTM_HDMI_FIXME
+       /* Setup and enable I2C subunit */
+       rc = hdmi_i2c_reset_init_enable(ctx);
+       if (rc != OTM_HDMI_SUCCESS)
+               goto exit;
+
+       /* Activate interrupts of interest */
+       hdmi_interrupts_set_mask(&ctx->dev, HDMI_INTERRUPTS);
+
+       /* Bring device to a known state */
+       hdmi_general_pixel_clock_enable(&ctx->dev);
+       hdmi_general_tdms_clock_enable(&ctx->dev);
+       hdmi_general_audio_clock_enable(&ctx->dev);
+       hdmi_general_hdcp_clock_enable(&ctx->dev);
+       hdmi_general_5V_enable(&ctx->dev);
+#endif
+
+#ifdef SOC_HDCP_ENABLE
+       hdmi_hdcp_disable(ctx);
+#endif
+
+exit:
+       return rc;
+}
+
+static void log_entry(void *uhandle, char *foo)
+{
+#ifdef __HDMI_HAL_TRACE__
+       PD_PRINT("%s: Entering %s\n", PD_NAME, foo);
+#endif
+}
+
+static void log_exit(void *uhandle, char *foo, int rc)
+{
+#ifdef __HDMI_HAL_TRACE__
+       PD_PRINT("%s: Exiting %s with %d\n", PD_NAME, foo, rc);
+#endif
+}
+
+/* Microseconds domain timer initialization */
+static void __poll_start(void *poll_timer)
+{
+       do_gettimeofday(poll_timer);
+}
+
+/* Microseconds domain timeout verification */
+static bool __poll_timeout(void *poll_timer)
+{
+       struct timeval tv_stop;
+       do_gettimeofday(&tv_stop);
+       return TIME_DIFF(tv_stop, *((struct timeval *) poll_timer)) >
+                               I2C_SW_TIMEOUT;
+}
+
+static otm_hdmi_ret_t __hdmi_context_init(void *context, struct pci_dev *pdev)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       hdmi_context_t *ctx = NULL;
+       unsigned int isr_address;
+
+       PD_LOG_ENTRY(PD_LOG_LEVEL_HIGH);
+
+       /* Verify pointers */
+       if (context == NULL) {
+               rc = OTM_HDMI_ERR_INTERNAL;
+               goto exit;
+       }
+       ctx = (hdmi_context_t *)context;
+
+       rc = ps_hdmi_pci_dev_init(ctx, pdev);
+       if (rc != OTM_HDMI_SUCCESS)
+               goto exit;
+
+#ifndef OTM_HDMI_FIXME
+/* FIXME: this should come from IPIL */
+#define        HDMI_INTERRUPT_STATUS 0x100C
+#endif
+       /* Register for interrupt routine invocation at given interrupt */
+       isr_address = (unsigned int)ctx->io_address + HDMI_INTERRUPT_STATUS;
+
+       pr_debug("About to call initialize HAL members and io_address "
+                       "is 0x%x\n",
+                       (unsigned int)ctx->io_address);
+
+       /* Initialize HAL; It's important that ALL entries are initialized!!! */
+       ctx->dev.usleep = 0;
+       ctx->dev.log_entry = log_entry;
+       ctx->dev.log_exit = log_exit;
+       ctx->dev.poll_timer = &ctx->hal_timer;
+       ctx->dev.poll_start = __poll_start;
+       ctx->dev.poll_timeout = __poll_timeout;
+       ctx->dev.io_address = (unsigned int)ctx->io_address;
+       ctx->dev.io_address = (unsigned int)ctx->io_address;
+#ifdef OTM_HDMI_FIXME
+       ctx->dev.io_read = ior;
+       ctx->dev.io_write = iow;
+#endif
+
+       ctx->dev.uhandle = ctx->io_address;
+       /* Create modes table sharing protection semaphore */
+       mutex_init (&ctx->modes_sema);
+
+       /* Create execution protection semaphore */
+       mutex_init (&ctx->exec_sema);
+
+       /* Create HPD protection semaphore */
+       mutex_init (&ctx->hpd_sema);
+
+       /* Create server thread synchronization semaphore */
+       mutex_init (&ctx->srv_sema);
+
+       /* Create server thread synchronization semaphore */
+       mutex_init (&ctx->i2c_sema);
+
+       /* Create AV mute synchronization semaphore */
+       mutex_init (&ctx->mute_sema);
+
+exit:
+       PD_LOG_EXIT(PD_LOG_LEVEL_HIGH, rc);
+       return rc;
+}
+
+void otm_hdmi_deinit(void *context)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       hdmi_context_t *ctx = NULL;
+
+       PD_LOG_ENTRY(PD_LOG_LEVEL_HIGH);
+
+       /* Verify pointers */
+       if (context == NULL) {
+               rc = OTM_HDMI_ERR_INTERNAL;
+               goto exit;
+       }
+       ctx = context;
+
+#ifdef OTM_HDMI_FIXME
+       /* Disable interrupts and unregister interrupts handling routine */
+       hdmi_interrupts_set_mask(&ctx->dev, 0);
+       free_irq(ctx->irq_number, ctx);
+#endif
+       /* Destroy semaphores */
+       mutex_destroy(&ctx->modes_sema);
+       mutex_destroy(&ctx->exec_sema);
+       mutex_destroy(&ctx->hpd_sema);
+       mutex_destroy(&ctx->srv_sema);
+       mutex_destroy(&ctx->i2c_sema);
+       mutex_destroy(&ctx->mute_sema);
+
+       /* Bring device to a known state */
+#ifdef OTM_HDMI_FIXME
+#ifdef SOC_HDMI_VIDEO_ENABLE
+       hdmi_video_set_pixel_source(&ctx->dev, false);
+#endif
+#ifdef SOC_HDMI_INFOFRAMES_ENABLE
+       hdmi_infoframe_disable_all(&ctx->dev);
+#endif
+#endif
+       ipil_hdmi_general_unit_disable(&ctx->dev);
+#ifdef OTM_HDMI_FIXME
+       /* Disable PHY */
+       rc = __hdmi_phy_enable(ctx, false);
+       pr_debug("__hdmi_phy_enable returned with %d\n", rc);
+#endif
+       ipil_hdmi_general_hdcp_clock_disable(&ctx->dev);
+       ipil_hdmi_general_5V_disable(&ctx->dev);
+       ipil_hdmi_general_audio_clock_disable(&ctx->dev);
+       ipil_hdmi_general_pixel_clock_disable(&ctx->dev);
+       ipil_hdmi_general_tdms_clock_disable(&ctx->dev);
+       ipil_hdmi_i2c_disable(&ctx->dev);
+
+       /* Clearing audio information */
+       ipil_hdmi_audio_deinit(ctx);
+
+       /* Unmap IO region, Disable the PCI devices
+        */
+       rc = ps_hdmi_pci_dev_deinit(ctx);
+
+       /* Free context */
+       kfree(ctx);
+
+       pr_debug("Exiting deinit with error code %d\n", rc);
+exit:
+       PD_LOG_EXIT(PD_LOG_LEVEL_HIGH, rc);
+       return;
+}
+
+#ifndef OTM_HDMI_FIXME
+otm_hdmi_ret_t hdmi_phy_enable(hdmi_device_t *dev, bool status)
+{
+       return OTM_HDMI_SUCCESS;
+}
+
+otm_hdmi_ret_t hdmi_timing_add_twin_entries(edid_info_t *edid,
+                                           otm_hdmi_refresh_t src,
+                                           otm_hdmi_refresh_t dst)
+{
+       return OTM_HDMI_SUCCESS;
+}
+
+void hdmi_timing_edid_to_vdc(otm_hdmi_timing_t *t)
+{
+       return;
+}
+#endif
+
+/* turn HDMI power rails on */
+bool otm_hdmi_power_rails_on()
+{
+       return ipil_hdmi_power_rails_on();
+}
+
+/* get pixel clock range */
+otm_hdmi_ret_t otm_hdmi_get_pixel_clock_range(unsigned int *pc_min,
+                                               unsigned int *pc_max)
+{
+       if (!pc_min || !pc_max)
+               return OTM_HDMI_ERR_FAILED;
+
+       *pc_min = IPIL_MIN_PIXEL_CLOCK;
+       *pc_max = IPIL_MAX_PIXEL_CLOCK;
+       return OTM_HDMI_SUCCESS;
+}
+
+/*
+ * Description: hdmi interrupt handler (upper half).
+ *             handles the interrupts by reading hdmi status register
+ *             and waking up bottom half if needed.
+ *
+ * @irq:       irq number
+ * @data:      data for the interrupt handler
+ *
+ * Returns:    IRQ_HANDLED on NULL input arguments, and if the
+ *                     interrupt is not HDMI HPD interrupts.
+ *             IRQ_WAKE_THREAD if this is a HDMI HPD interrupt.
+ */
+static irqreturn_t __hdmi_irq_handler(int irq, void *data)
+{
+       if (g_context != NULL)
+               return ipil_hdmi_irq_handler(&g_context->dev);
+
+       return IRQ_HANDLED;
+}
+
+/**
+ *     otm_hdmi_setup_irq      -       install HPD IRQ call back
+ *     @context: hdmi device context
+ *     @pdev: pci device
+ *     @phdmi_irq_cb: function pointer for hotplug/unplug IRQ callbacks.
+ *     data: data for irq callback
+ *
+ *     Perform HPD IRQ call back initialization
+ *
+ *     Returns - check otm_hdmi_ret_t
+ */
+otm_hdmi_ret_t otm_hdmi_setup_irq(void *context, struct pci_dev *pdev,
+                               irqreturn_t (*phdmi_irq_cb) (int, void*),
+                               void *data)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       hdmi_context_t *ctx = NULL;
+       int ret;
+
+       /* Verify pointers */
+       if (context == NULL) {
+               rc = OTM_HDMI_ERR_INTERNAL;
+               goto exit;
+       }
+       ctx = (hdmi_context_t *)context;
+
+       /* Setup interrupt handler */
+       if (phdmi_irq_cb != NULL && data != NULL) {
+               ret = request_threaded_irq(ctx->irq_number,
+                               __hdmi_irq_handler, phdmi_irq_cb,
+                                IRQF_SHARED,OTM_HDMI_NAME, (void *)data);
+               if (ret) {
+                       pr_debug("\nregister irq interrupt failed\n");
+                       rc = OTM_HDMI_ERR_INTERNAL;
+                       /*
+                       * TODO: ignore failure as PCI is not working on DV1.
+                       */
+                       goto exit;
+               }
+       }
+exit:
+       return rc;
+
+}
+
+/**
+ *     otm_hdmi_device_init    -       init hdmi device driver
+ *     @context: hdmi device context
+ *     @pdev: pci device
+ *
+ *     Perform HDMI device initialization which includes 3 steps:
+ *     1) otm context create,
+ *     2) os specific context init,
+ *     3) device enable
+ *
+ *     Returns - check otm_hdmi_ret_t
+ */
+otm_hdmi_ret_t otm_hdmi_device_init(void **context, struct pci_dev *pdev)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       hdmi_context_t *ctx = NULL;
+       int n;
+       int ret;
+
+       PD_LOG_ENTRY(PD_LOG_LEVEL_HIGH);
+
+       /* Verify pointers */
+       if (context == NULL) {
+               rc = OTM_HDMI_ERR_INTERNAL;
+               goto exit;
+       }
+
+       /* Create and clear context */
+       g_context = ctx =
+           (hdmi_context_t *) kmalloc(sizeof(hdmi_context_t), GFP_KERNEL);
+       if (ctx == NULL) {
+               rc = OTM_HDMI_ERR_NO_MEMORY;
+               goto exit;
+       }
+       memset(ctx, 0, sizeof(hdmi_context_t));
+
+       pr_debug("HDMI Context created = 0x%08x\n", (unsigned int)ctx);
+
+       /* Init HDMI context */
+       rc = __hdmi_context_init(ctx, pdev);
+       if (rc != OTM_HDMI_SUCCESS) {
+               pr_debug("\nHDMI Context init failed\n");
+               goto exit;
+       }
+
+       rc = otm_hdmi_declare_attributes(__pd_attr_declare, __pd_attr_get_name);
+       if (rc != OTM_HDMI_SUCCESS) {
+               pr_debug("\nHDMI declare attributes table failed\n");
+               goto exit;
+       }
+
+       ipil_hdmi_set_hdmi_dev(&ctx->dev);
+
+       /* Decide on I2C HW acceleration */
+       ipil_hdmi_decide_I2C_HW(ctx);
+
+       /* Save the output mode as DTV or HDMT tx */
+       ctx->dtv = g_dtv;
+
+       /* Save the deep color enable flag */
+       ctx->dc = g_dc;
+
+       /* Explicitly disable 5V before enabling it later as transition from
+        * off to on seems to be responsible to hot plug generation during
+        * starup */
+       ipil_hdmi_general_5V_disable(&ctx->dev);
+
+       /* Save active GPIO number */
+       ctx->gpio = g_gpio;
+
+       /* Save context */
+       *context = ctx;
+
+       /* Setup all external clocks */
+       rc = ipil_hdmi_set_program_clocks(ctx, 27000);
+       if (rc != OTM_HDMI_SUCCESS)
+               goto exit;
+
+       /* Fill in static timing table */
+       n = __init_tx_modes(ctx->dev.id, g_video_modes, MAX_TIMINGS,
+                               false);
+       if (n < 0) {
+               rc = OTM_HDMI_ERR_NO_MEMORY;
+               goto exit;
+       }
+       ctx->n_modes_tx = n;
+
+       /* Fill EDID parser reference timing table */
+       n = __init_tx_modes(ctx->dev.id, g_video_modes_ref, MAX_TIMINGS,
+                           true);
+       if (n < 0) {
+               rc = OTM_HDMI_ERR_NO_MEMORY;
+               goto exit;
+       }
+       ctx->n_modes_ref = n;
+
+       /* Fill in advertised timings table */
+       otm_hdmi_edid_parse(ctx, OTM_HDMI_USE_EDID_NONE);
+
+#ifdef OTM_HDMI_FIXME
+       /* Enable HDMI unit */
+       rc = __hdmi_enable(ctx);
+       if (rc != OTM_HDMI_SUCCESS)
+               goto exit;
+#endif
+       rc = ipil_hdmi_audio_init(ctx);
+       if (rc != OTM_HDMI_SUCCESS)
+               goto exit;
+
+exit:
+       /* Clean up if appropriate */
+       if ((rc != OTM_HDMI_SUCCESS) && (ctx != NULL))
+               otm_hdmi_deinit((void *)ctx);
+
+       PD_LOG_EXIT(PD_LOG_LEVEL_HIGH, rc);
+       return rc;
+}
+
+bool otm_hdmi_is_preferred_mode(int hdisplay, int vdisplay, int refresh)
+{
+       if (hdisplay == IPIL_PREFERRED_HDISPLAY &&
+           vdisplay == IPIL_PREFERRED_VDISPLAY &&
+           refresh == IPIL_PREFERRED_REFRESH_RATE)
+               return true;
+       else
+               return false;
+}
+
+otm_hdmi_ret_t otm_hdmi_set_raw_edid(void *context, char *raw_edid)
+{
+       hdmi_context_t *ctx = (hdmi_context_t *)context;
+
+       if (ctx == NULL)
+               return OTM_HDMI_ERR_FAILED;
+
+       /* TODO: need more flexiable way which should be edid size-aware copy */
+       memcpy(ctx->edid_raw, raw_edid, MAX_EDID_BLOCKS * SEGMENT_SIZE);
+
+       return OTM_HDMI_SUCCESS;
+}
+
+otm_hdmi_ret_t otm_hdmi_get_raw_edid(void *context, char **raw_edid)
+{
+       hdmi_context_t *ctx = (hdmi_context_t *)context;
+
+       if (ctx == NULL || raw_edid == NULL)
+               return OTM_HDMI_ERR_FAILED;
+
+       *raw_edid = (char *)ctx->edid_raw;
+
+       return OTM_HDMI_SUCCESS;
+}
+
+bool otm_hdmi_is_monitor_hdmi(void *context)
+{
+       hdmi_context_t *ctx = (hdmi_context_t *)context;
+
+       if (ctx == NULL)
+               return true; /* default to HDMI */
+
+       return ctx->edid_int.hdmi;
+}
+
+/*
+ * HDMI video mute handling
+ */
+void hdmi_mute(hdmi_context_t *ctx, otm_hdmi_mute_t type, mute_source_t source)
+{
+#ifdef OTM_HDMI_FIXME
+       unsigned int color = PD_ATTR_UINT(ATTRS[OTM_HDMI_ATTR_ID_BG_COLOR]);
+       hdmi_video_set_pixel_color(&ctx->dev, color);
+#endif
+       mutex_lock(&ctx->mute_sema);
+       if (type & OTM_HDMI_MUTE_VIDEO) {
+               /*
+                * Update mute list and mute video
+                */
+               ctx->mute_source |= source;
+#ifdef OTM_HDMI_FIXME
+               hdmi_video_set_pixel_source(&ctx->dev, false);
+#endif
+       } else {
+               /*
+                * Update mute list and unmute video [if possible]
+                */
+               ctx->mute_source &= ~source;
+#ifdef OTM_HDMI_FIXME
+               hdmi_video_set_pixel_source(&ctx->dev, ctx->mute_source == 0);
+#endif
+       }
+       mutex_unlock(&ctx->mute_sema);
+}
+
+/*
+ * __check_opd_support()
+ */
+static otm_hdmi_ret_t __check_opd_support(otm_hdmi_output_pixel_depth_t depth,
+                                                       bool depth_30,
+                                                       bool depth_36)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_ERR_INTERNAL;
+
+       switch (depth) {
+       case OTM_HDMI_OPD_24BIT:
+               rc = OTM_HDMI_SUCCESS;
+               break;
+       case OTM_HDMI_OPD_30BIT:
+               rc = depth_30 ? OTM_HDMI_SUCCESS : rc;
+               break;
+       case OTM_HDMI_OPD_36BIT:
+               rc = depth_36 ? OTM_HDMI_SUCCESS : rc;
+               break;
+       default:
+               rc = OTM_HDMI_ERR_INTERNAL;
+               break;
+       }
+
+       return rc;
+}
+
+/*
+ * __check_pixel_depth_cfg()
+ */
+static otm_hdmi_ret_t __check_pixel_depth_cfg(
+                               otm_hdmi_output_pixel_format_t opf,
+                               otm_hdmi_output_pixel_depth_t opd)
+{
+       bool rc = (opf != OTM_HDMI_OPF_YUV422)
+           || (opd == OTM_HDMI_OPD_24BIT);
+       return rc ? OTM_HDMI_SUCCESS : OTM_HDMI_ERR_INTERNAL;
+}
+
+/*
+ * __check_opf_support()
+ */
+static otm_hdmi_ret_t __check_opf_support(otm_hdmi_output_pixel_format_t format,
+                                               bool yuv444,
+                                               bool yuv422)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_ERR_INTERNAL;
+       bool ext_color =
+           PD_ATTR_BOOL(ATTRS[OTM_HDMI_ATTR_ID_COLOR_SPACE_EXT]);
+
+       switch (format) {
+       case OTM_HDMI_OPF_YUV444:
+               rc = yuv444 ? OTM_HDMI_SUCCESS : rc;
+               break;
+       case OTM_HDMI_OPF_YUV422:
+               rc = yuv422 ? OTM_HDMI_SUCCESS : rc;
+               break;
+       case OTM_HDMI_OPF_RGB444:
+               rc = (!ext_color) ? OTM_HDMI_SUCCESS : rc;
+               break;
+       default:
+               rc = OTM_HDMI_ERR_INTERNAL;
+               break;
+       }
+
+       return rc;
+}
+
+/*
+ * __set_attr_csc()
+ */
+static otm_hdmi_ret_t __set_attr_csc(hdmi_context_t *ctx)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       int in, out;
+
+       if (NULL == ctx) {
+               PD_LOG_ERROR("Invalid argument passed (ctx)\n");
+               rc = OTM_HDMI_ERR_FAILED;
+               goto exit;
+       }
+       /*
+        * Set CSC appropriately
+        */
+       out = PD_ATTR_UINT(ATTRS[OTM_HDMI_ATTR_ID_PIXEL_FORMAT_OUTPUT]);
+       in = PD_ATTR_UINT(ATTRS[OTM_HDMI_ATTR_ID_COLOR_SPACE_INPUT]);
+#ifdef OTM_HDMI_FIXME
+       rc = hdmi_configure_csc(&ctx->dev, in, out, &ctx->mode);
+#endif
+
+exit:
+       return rc;
+}
+
+/**
+ *     otm_hdmi_attr_set_validate - validates the attribute to
+ *                                     be written or not.
+ *
+ *     Write's the attributes value.
+ *
+ *     Returns -
+ *             OTM_HDMI_SUCCESS - if the attribute value is writable.
+ *             OTM_HDMI_ERR_INTERNAL - if the attribute value is non-writable.
+ *             OTM_HDMI_ERR_FAILED - if the attribute is not in range.
+ */
+static otm_hdmi_ret_t otm_hdmi_attr_set_validate(otm_hdmi_attribute_id_t id,
+                                               void *value)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       bool _bool;
+       unsigned int _uint;
+       char *_string = NULL;
+       int str_len = 0;
+
+       if (id < 0 || id > OTM_HDMI_MAX_SUPPORTED_ATTRIBUTES) {
+               PD_LOG_ERROR("Invalid argument passed (id): %d\n", id);
+               rc = OTM_HDMI_ERR_FAILED;
+               goto exit;
+       }
+       if (NULL == value) {
+               PD_LOG_ERROR("Invalid argument passed (value): %d\n", id);
+               rc = OTM_HDMI_ERR_FAILED;
+               goto exit;
+       }
+
+       if (OTM_HDMI_ATTR_FLAG_WRITE != ATTRS[id].flags) {
+               PD_LOG_ERROR("Attribute id: %d is read-only\n", id);
+               rc = OTM_HDMI_ERR_FAILED;
+               goto exit;
+       }
+
+       /*
+        * Based on attribute type perform appropriate check
+        */
+       switch (ATTRS[id].type) {
+       case OTM_HDMI_ATTR_TYPE_BOOLEAN:
+               _bool = *(bool *) value;
+               if ((_bool != true) && (_bool != false))
+                       rc = OTM_HDMI_ERR_FAILED;
+               break;
+
+       case OTM_HDMI_ATTR_TYPE_UINT:
+               _uint = *(unsigned int *)value;
+               if ((_uint < ATTRS[id].content._uint.value_min)
+                   || (_uint > ATTRS[id].content._uint.value_max)) {
+                       rc = OTM_HDMI_ERR_FAILED;
+               }
+               break;
+
+       case OTM_HDMI_ATTR_TYPE_STRING:
+               _string = (char *) value;
+               str_len = strlen(_string);
+               if (str_len < 1 || str_len > OTM_HDMI_MAX_STRING_LENGTH) {
+                       rc = OTM_HDMI_ERR_FAILED;
+                       goto exit;
+               }
+               break;
+       default:
+               PD_LOG_ERROR("Invalid attribute id (%d)\n", id);
+               rc = OTM_HDMI_ERR_FAILED;
+               break;
+       }
+
+exit:
+       PD_LOG_EXIT(PD_LOG_LEVEL_HIGH, rc);
+       return rc;
+}
+
+/*
+ * Setting given attribute
+ * @param [in] context : port driver specific information
+ * @param [in] id       : attribute id
+ * @param [in] data     : user provided buffer with attribute value
+ * @param [in] internal : internal [driver] or external [app] call
+
+ * Note: Some attributes settings can not be applied until mode change was done.
+ * Hence such attributes are set logically and the actual HW will be set during
+ * mode change.
+ */
+otm_hdmi_ret_t otm_hdmi_set_attribute(void *context,
+                                       otm_hdmi_attribute_id_t id,
+                                       void *data,
+                                       bool internal)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       hdmi_context_t *ctx = (hdmi_context_t *) context;
+#ifdef OTM_HDMI_FIXME
+       gdl_display_id_t pipe =
+           PD_ATTR_UINT(ATTRS[OTM_HDMI_ATTR_ID_DISPLAY_PIPE]);
+       otm_hdmi_ret_t rc1, rc2;
+       bool hdcp_ctrl = PD_ATTR_BOOL(ATTRS[OTM_HDMI_ATTR_ID_HDCP]);
+       otm_hdmi_hdcp_status_t hdcp_status =
+               PD_ATTR_UINT(ATTRS[OTM_HDMI_ATTR_ID_HDCP_STATUS]);
+#endif
+       bool pwr = PD_ATTR_BOOL(ATTRS[OTM_HDMI_ATTR_ID_POWER]);
+       edid_info_t *edid;
+       bool abool;
+       unsigned int auint, out, depth;
+       otm_hdmi_attribute_flag_t flags;
+       PD_LOG_ENTRY(PD_LOG_LEVEL_HIGH);
+
+       if (NULL == ctx) {
+               PD_LOG_ERROR("Invalid argument passed (context): %d\n", id);
+               rc = OTM_HDMI_ERR_FAILED;
+               goto exit;
+       }
+       flags =
+           OTM_HDMI_ATTR_FLAG_WRITE |
+               (internal ? OTM_HDMI_ATTR_FLAG_INTERNAL : 0);
+
+       rc = otm_hdmi_attr_set_validate(id, data);
+       if (OTM_HDMI_SUCCESS != rc)
+               goto exit;
+       abool = *(bool *) (data);
+       auint = *(unsigned int *) (data);
+       PD_LOG_PRINT(PD_LOG_LEVEL_HIGH, "ATTR[%d] -> %d\n", id, auint);
+
+#ifdef OTM_HDMI_FIXME
+       /*
+        * If not on pipe 0 all requests
+        * [except new pipe setting] must be rejected
+        */
+       if (pipe == GDL_DISPLAY_ID_UNDEFINED
+           && id != OTM_HDMI_ATTR_ID_DISPLAY_PIPE) {
+               rc = OTM_HDMI_ERR_FAILED;
+               goto exit;
+       }
+
+       rc = __update_edid(ctx);
+       if (rc != OTM_HDMI_SUCCESS) {
+               PD_LOG_ERROR("ERR: %s at %d code = %d\n",
+                               __func__, __LINE__, rc);
+               goto exit;
+       }
+#endif
+       edid = &ctx->edid_ext;
+
+       switch (id) {
+       case OTM_HDMI_ATTR_ID_PIXEL_FORMAT_OUTPUT:
+               out = auint;
+               depth =
+                       ctx->dc ? PD_ATTR_UINT(ATTRS
+                               [OTM_HDMI_ATTR_ID_PIXEL_DEPTH]) :
+                               OTM_HDMI_OPD_24BIT;
+               rc = __check_opf_support(out, edid->ycbcr444, edid->ycbcr422);
+               if (OTM_HDMI_SUCCESS != rc)
+                       goto exit;
+               rc = __check_pixel_depth_cfg(out, depth);
+               if (OTM_HDMI_SUCCESS != rc)
+                       goto exit;
+#ifdef OTM_HDMI_FIXME
+               rc = ctx->support->pd_setmode_required(pipe);
+               if (rc != OTM_HDMI_SUCCESS) {
+                       PD_LOG_ERROR("ERR: %s at %d code = %d\n",
+                                       __func__, __LINE__, rc);
+                       goto exit;
+               }
+#endif
+               break;
+
+       case OTM_HDMI_ATTR_ID_PIXEL_DEPTH:
+               if (false == ctx->dc) {
+                       rc = OTM_HDMI_ERR_FAILED;
+                       goto exit;
+               }
+               depth = auint;
+               out = PD_ATTR_UINT(ATTRS
+                               [OTM_HDMI_ATTR_ID_PIXEL_FORMAT_OUTPUT]);
+
+               rc = __check_opd_support(depth, edid->dc_30, edid->dc_36);
+               if (OTM_HDMI_SUCCESS != rc)
+                       goto exit;
+
+               rc = __check_pixel_depth_cfg(out, depth);
+               if (OTM_HDMI_SUCCESS != rc)
+                       goto exit;
+
+#ifdef OTM_HDMI_FIXME
+               rc = ctx->support->pd_setmode_required(pipe);
+               if (rc != OTM_HDMI_SUCCESS) {
+                       PD_LOG_ERROR("ERR: %s at %d code = %d\n",
+                                       __func__, __LINE__, rc);
+                       goto exit;
+               }
+#endif
+               break;
+
+       case OTM_HDMI_ATTR_ID_HDCP:
+               if (true == ctx->dtv) {
+                       rc = OTM_HDMI_ERR_FAILED;
+                       goto exit;
+               }
+#ifdef OTM_HDMI_FIXME
+               rc = (abool != hdcp_ctrl) ? service_hdcp_set(ctx, abool,
+                                               !abool) :
+                                               OTM_HDMI_SUCCESS;
+#endif
+               if (OTM_HDMI_SUCCESS != rc)
+                       goto exit;
+               break;
+#ifdef OTM_HDMI_FIXME
+       case OTM_HDMI_ATTR_ID_BG_COLOR:
+               rc  = hdmi_video_set_pixel_color(&ctx->dev, auint);
+               if (rc != OTM_HDMI_SUCCESS) {
+                       PD_LOG_ERROR("ERR: %s at %d code = %d\n",
+                                       __func__, __LINE__, rc);
+                       goto exit;
+               }
+               break;
+#endif
+       case OTM_HDMI_ATTR_ID_USE_EDID:
+               if (true == ctx->dtv) {
+                       rc = OTM_HDMI_ERR_FAILED;
+                       goto exit;
+               }
+
+               rc = otm_hdmi_edid_parse(ctx, auint);
+               if (OTM_HDMI_SUCCESS != rc)
+                       goto exit;
+#ifdef OTM_HDMI_FIXME
+               rc  = ctx->support->pd_setmode_required(pipe);
+               if (rc != OTM_HDMI_SUCCESS) {
+                       PD_LOG_ERROR("ERR: %s at %d code = %d\n",
+                                       __func__, __LINE__, rc);
+                       goto exit;
+               }
+#endif
+               break;
+
+       case OTM_HDMI_ATTR_ID_POWER:
+               if (abool != pwr) {
+                       /*
+                        * When shutting down the PHY also disable HDCP
+                        * Some sinks are picky to PHY going off
+                        * when input is encrypted PHY enabling expects
+                        * HDCP to be off for unmute to happen
+                        */
+                       if (!abool) {
+#ifdef OTM_HDMI_FIXME
+                               rc = service_hdcp_set(ctx, false,
+                                                       true);
+                               if (rc != OTM_HDMI_SUCCESS) {
+                                       PD_LOG_ERROR("ERR: %s at %d code :%d\n",
+                                                __func__, __LINE__, rc);
+                                       goto exit;
+                               }
+#endif
+                       }
+                       rc = hdmi_phy_enable(&(ctx->dev), abool);
+                       if (OTM_HDMI_SUCCESS != rc)
+                               goto exit;
+#ifdef OTM_HDMI_FIXME
+                       ctx->support->pd_submit_event
+                               (GDL_APP_EVENT_PHY_STATUS_CHANGE);
+#endif
+               }
+               break;
+
+       case OTM_HDMI_ATTR_ID_SLOW_DDC:
+#ifdef OTM_HDMI_FIXME
+               rc = hdmi_i2c_set_ddc_speed(&ctx->dev, abool);
+               if (rc != OTM_HDMI_SUCCESS) {
+                       PD_LOG_ERROR("ERR: %s at %d code = %d\n",
+                                       __func__, __LINE__, rc);
+                       goto exit;
+               }
+#endif
+               break;
+
+       case OTM_HDMI_ATTR_ID_COLOR_SPACE_EXT:
+               if (abool) {
+                       /*
+                        * xvYCC colorimetry can only be set
+                        * if we are outputing YCbCr
+                        */
+                       out = PD_ATTR_UINT(ATTRS
+                               [OTM_HDMI_ATTR_ID_PIXEL_FORMAT_OUTPUT]);
+                       if (OTM_HDMI_OPF_RGB444 == out) {
+                               rc = OTM_HDMI_ERR_FAILED;
+                               goto exit;
+                       }
+#ifdef OTM_HDMI_FIXME
+                       /*
+                        * xvYCC colorimetry can only be set
+                        * if we are sending gamut packets
+                        */
+                       rc1 =
+                           hdmi_packet_check_type(&ctx->pi_0.packet,
+                                                  HDMI_PACKET_GAMUT);
+                       rc2 =
+                           hdmi_packet_check_type(&ctx->pi_1.packet,
+                                                  HDMI_PACKET_GAMUT);
+#endif
+               }
+               if (false == ctx->usr_avi) {
+                       rc = OTM_HDMI_ERR_FAILED;
+                       goto exit;
+               }
+               break;
+
+       case OTM_HDMI_ATTR_ID_DISPLAY_PIPE:
+#ifdef OTM_HDMI_FIXME
+               if (GDL_DISPLAY_ID_1 == auint) {
+                       rc = OTM_HDMI_ERR_FAILED;
+                       goto exit;
+               }
+               if (pipe == pipe)
+                       goto exit;
+               rc = __switch_pipe(ctx);
+               if (rc != OTM_HDMI_SUCCESS) {
+                       PD_LOG_ERROR("ERR: %s at %d code = %d\n",
+                                       __func__, __LINE__, rc);
+                       goto exit;
+               }
+#endif
+               break;
+
+       case OTM_HDMI_ATTR_ID_MUTE:
+               /*
+                * Audio mute is handled indirectly
+                * during writes based on attribute value
+                * Video mute needs to be handled directly
+                */
+               hdmi_mute(ctx, auint, MUTE_SOURCE_APP);
+               break;
+
+       case OTM_HDMI_ATTR_ID_PURE_VIDEO:
+#ifdef OTM_HDMI_FIXME
+               rc = hdmi_video_set_video_indicator(&ctx->dev, abool);
+               if (rc != OTM_HDMI_SUCCESS) {
+                       PD_LOG_ERROR("ERR: %s at %d code = %d\n",
+                                       __func__, __LINE__, rc);
+                       goto exit;
+               }
+#endif
+               break;
+
+       case OTM_HDMI_ATTR_ID_OUTPUT_DITHER:
+#ifdef OTM_HDMI_FIXME
+               rc = ctx->support->pd_setmode_required(pipe);
+               if (rc != OTM_HDMI_SUCCESS) {
+                       PD_LOG_ERROR("ERR: %s at %d code = %d\n",
+                                       __func__, __LINE__, rc);
+                       goto exit;
+               }
+#endif
+               break;
+
+       case OTM_HDMI_ATTR_ID_HDCP_ENCRYPT:
+#ifdef OTM_HDMI_FIXME
+               rc = hdmi_hdcp_set_enc(ctx, abool && HDCP_OFF != hdcp_status);
+               if (rc != OTM_HDMI_SUCCESS) {
+                       PD_LOG_ERROR("ERR: %s at %d code = %d\n",
+                                       __func__, __LINE__, rc);
+                       goto exit;
+               }
+#endif
+               break;
+
+       case OTM_HDMI_ATTR_ID_DVI:
+#ifdef OTM_HDMI_FIXME
+               rc = ctx->support->pd_setmode_required(pipe);
+               if (rc != OTM_HDMI_SUCCESS) {
+                       PD_LOG_ERROR("ERR: %s at %d code = %d\n",
+                                       __func__, __LINE__, rc);
+                       goto exit;
+               }
+#endif
+               break;
+
+       case OTM_HDMI_ATTR_ID_PAR:
+       case OTM_HDMI_ATTR_ID_FAR:
+               if (false == ctx->usr_avi) {
+                       rc = OTM_HDMI_ERR_FAILED;
+                       goto exit;
+               }
+               break;
+
+       default:
+               break;
+       }
+
+#ifdef OTM_HDMI_FIXME
+       rc = ctx->support->pd_attr_set(ATTRS, id, data, flags);
+       if (rc != OTM_HDMI_SUCCESS) {
+               PD_LOG_ERROR("ERR: %s at %d code = %d\n",
+                               __func__, __LINE__, rc);
+               goto exit;
+       }
+#endif
+       /*
+        * Post processing [here we call routines
+        * that rely on the value in the ATTR
+        * table which are not yet available
+        * during the switch statement above
+        */
+       switch (id) {
+       case OTM_HDMI_ATTR_ID_COLOR_SPACE_INPUT:
+               rc = (ctx->mode_set) ? __set_attr_csc(ctx) : rc;
+               break;
+
+       case OTM_HDMI_ATTR_ID_OUTPUT_CLAMP:
+               rc = (ctx->mode_set) ? __set_attr_csc(ctx) : rc;
+               if (false == ctx->usr_avi)
+                       goto exit;
+
+       case OTM_HDMI_ATTR_ID_PAR:
+       case OTM_HDMI_ATTR_ID_FAR:
+       case OTM_HDMI_ATTR_ID_COLOR_SPACE_EXT:
+               rc = (ctx->mode_set) ?
+                       otm_hdmi_infoframes_set_avi(ctx,
+                       &ctx->mode) : rc;
+               break;
+
+       default:
+               break;
+       }
+
+exit:
+       PD_LOG_EXIT(PD_LOG_LEVEL_HIGH, rc);
+       return rc;
+}
+EXPORT_SYMBOL(otm_hdmi_set_attribute);
+
+/**
+ *     otm_hdmi_attr_get_validate - validates the attribute
+ *                                     to be read or not.
+ *
+ *     Read's the attributes flag value.
+ *
+ *     Returns -
+ *             OTM_HDMI_SUCCESS - if the attribute is readable.
+ *             OTM_HDMI_ERR_INTERNAL - if the attribute is non-readable.
+ *             OTM_HDMI_ERR_FAILED - if the attribute is not in range.
+ */
+static otm_hdmi_ret_t otm_hdmi_attr_get_validate(otm_hdmi_attribute_id_t id)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       if (id < 0 || id > OTM_HDMI_MAX_SUPPORTED_ATTRIBUTES) {
+               PD_LOG_ERROR("Invalid argument passed (id): %d\n", id);
+               rc = OTM_HDMI_ERR_FAILED;
+               goto exit;
+       }
+       /*
+        * Based on attribute type perform appropriate check
+       */
+       switch (ATTRS[id].flags) {
+       case OTM_HDMI_ATTR_FLAG_WRITE:
+               break;
+
+       case OTM_HDMI_ATTR_FLAG_SUPPORTED:
+               /*
+                * Needs a Fix.
+                */
+               rc = OTM_HDMI_SUCCESS;
+               break;
+
+       case OTM_HDMI_ATTR_FLAG_INTERNAL:
+               rc = OTM_HDMI_ERR_INTERNAL;
+               break;
+       default:
+               PD_LOG_ERROR("Invalid attribute accessed: (%d)\n", id);
+               rc = OTM_HDMI_ERR_FAILED;
+               break;
+       }
+exit:
+       PD_LOG_EXIT(PD_LOG_LEVEL_HIGH, rc);
+       return rc;
+}
+
+/*
+ *  Getting given attribute
+ *  @param [in ] id      : attribute id
+ *  @param [out] data    : user provided buffer for attribute details
+ *  @param [in ] log     : a hint wether port driver should log the call
+ */
+otm_hdmi_ret_t otm_hdmi_get_attribute(void *context,
+                                       otm_hdmi_attribute_id_t id,
+                                       otm_hdmi_attribute_t *attribute,
+                                       bool log)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       PD_LOG_ENTRY((log) ? PD_LOG_LEVEL_HIGH : PD_LOG_LEVEL_VBLANK);
+
+       rc = otm_hdmi_attr_get_validate(id);
+       if (OTM_HDMI_SUCCESS != rc)
+               goto exit;
+       if (NULL == attribute || NULL == context) {
+               PD_LOG_ERROR("Invalid argument passed (attribute): %d\n", id);
+               rc = OTM_HDMI_ERR_FAILED;
+               goto exit;
+       }
+
+       *attribute = ATTRS[id];
+exit:
+       PD_LOG_EXIT((log) ? PD_LOG_LEVEL_HIGH : PD_LOG_LEVEL_VBLANK, rc);
+       return rc;
+}
+EXPORT_SYMBOL(otm_hdmi_get_attribute);
+
+/**
+ *  Attribute name getting routine
+ */
+char *__pd_attr_get_name(otm_hdmi_attribute_id_t id)
+{
+       otm_hdmi_attribute_t *table = otm_hdmi_attributes_table;
+
+       if ((0 <= id) && (id < OTM_HDMI_MAX_SUPPORTED_ATTRIBUTES))
+               return table[id].name;
+       else
+               return NULL;
+}
+EXPORT_SYMBOL(__pd_attr_get_name);
+
+/**
+ *  Generic attribute declaration routine
+ */
+static otm_hdmi_ret_t __pd_attr_declare(otm_hdmi_attribute_t *table,
+                               otm_hdmi_attribute_id_t id,
+                               otm_hdmi_attribute_type_t type,
+                               otm_hdmi_attribute_flag_t flags,
+                               char *name,
+                               void *value,
+                               unsigned int min,
+                               unsigned int max)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+
+       if ((id < 0) || (id > OTM_HDMI_MAX_SUPPORTED_ATTRIBUTES))
+               return  OTM_HDMI_ERR_FAILED;
+
+       if ((name != NULL) && (strlen(name) < OTM_HDMI_MAX_STRING_LENGTH))
+               strncpy(table[id].name, name, strlen(name));
+       else if (strlen(table[id].name) == 0)
+               PD_LOG_ERROR("set default name\n");
+               /* TODO: set default name */
+
+       table[id].flags = flags;
+
+       switch (type) {
+       case OTM_HDMI_ATTR_TYPE_UINT:
+                       table[id].content._uint.value_default =
+                                               (unsigned int) value;
+                       table[id].content._uint.value_min = min;
+                       table[id].content._uint.value_max = max;
+                       break;
+       case OTM_HDMI_ATTR_TYPE_BOOLEAN:
+                       table[id].content._bool.value_default =
+                                               (bool) value;
+                       break;
+       case OTM_HDMI_ATTR_TYPE_STRING:
+                       if ((value != NULL) &&
+                       strlen(value) < OTM_HDMI_MAX_STRING_LENGTH)
+                               strncpy(table[id].content.string.value,
+                                                       (char *) value,
+                                                       strlen(value));
+                       else
+                               rc = OTM_HDMI_ERR_FAILED;
+                       break;
+       default:
+                       break;
+       }
+       return rc;
+}
+
+/**
+ *     otm_hdmi_declare_attributes - init hdmi global attributes table
+ *
+ *     Returns - check otm_hdmi_ret_t
+ */
+otm_hdmi_ret_t otm_hdmi_declare_attributes(pd_attr_declare_t declare,
+                                               pd_attr_get_name_t get_name)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+
+       otm_hdmi_attribute_t *table = otm_hdmi_attributes_table;
+
+       PD_LOG_ENTRY(PD_LOG_LEVEL_HIGH);
+
+       /*
+        * declare(table, OTM_HDMI_ATTR_ID_NAME,
+        * OTM_HDMI_ATTR_TYPE_STRING, PD_ATTR_FLAGS_RS,
+        * get_name(OTM_HDMI_ATTR_ID_NAME),
+        * (void *) PD_NAME, 0, 0);
+        */
+
+       PD_DECLARE_ATTRIBUTE_STRING(declare, table,
+               OTM_HDMI_ATTR_ID_NAME,
+               PD_ATTR_FLAGS_RS, get_name, PD_NAME);
+
+       PD_DECLARE_ATTRIBUTE_BOOL(declare, table,
+               OTM_HDMI_ATTR_ID_CABLE_STATUS,
+               PD_ATTR_FLAGS_RS, get_name, false);
+
+       PD_DECLARE_ATTRIBUTE_BOOL(declare, table,
+               OTM_HDMI_ATTR_ID_POWER,
+               PD_ATTR_FLAGS_RWS, get_name, true);
+
+       PD_DECLARE_ATTRIBUTE_BOOL(declare, table,
+               OTM_HDMI_ATTR_ID_HDCP,
+               PD_ATTR_FLAGS_RWS, get_name, true);
+
+       PD_DECLARE_ATTRIBUTE_BOOL(declare, table,
+               OTM_HDMI_ATTR_ID_HDCP_AUTO_MUTE,
+               PD_ATTR_FLAGS_RWS, get_name, true);
+
+       PD_DECLARE_ATTRIBUTE_UINT(declare, table,
+               OTM_HDMI_ATTR_ID_HDCP_STATUS,
+               PD_ATTR_FLAGS_RS, get_name,
+               OTM_HDMI_HDCP_STATUS_OFF,
+               OTM_HDMI_HDCP_STATUS_OFF,
+               OTM_HDMI_HDCP_STATUS_ON);
+
+       PD_DECLARE_ATTRIBUTE_BOOL(declare, table,
+               OTM_HDMI_ATTR_ID_HDCP_ENCRYPT,
+               PD_ATTR_FLAGS_RWS, get_name, true);
+
+       PD_DECLARE_ATTRIBUTE_UINT(declare, table,
+               OTM_HDMI_ATTR_ID_COLOR_SPACE_INPUT,
+               PD_ATTR_FLAGS_RWSI,
+               get_name,
+               OTM_HDMI_COLOR_SPACE_RGB,
+               0, OTM_HDMI_COLOR_SPACE_COUNT - 1);
+
+       PD_DECLARE_ATTRIBUTE_UINT(declare, table,
+               OTM_HDMI_ATTR_ID_PIXEL_FORMAT_OUTPUT,
+               PD_ATTR_FLAGS_RWS, get_name,
+               OTM_HDMI_OPF_RGB444, 0, OTM_HDMI_OPF_COUNT - 1);
+
+       PD_DECLARE_ATTRIBUTE_UINT(declare, table,
+               OTM_HDMI_ATTR_ID_PIXEL_DEPTH,
+               PD_ATTR_FLAGS_RWS,
+               get_name,
+               OTM_HDMI_OPD_24BIT,
+               0, OTM_HDMI_PIXEL_DEPTH_COUNT - 1);
+
+       PD_DECLARE_ATTRIBUTE_UINT(declare, table,
+               OTM_HDMI_ATTR_ID_BG_COLOR,
+               PD_ATTR_FLAGS_RWS,
+               get_name, 0xFF0000, 0x000000, 0xFFFFFF);
+
+       PD_DECLARE_ATTRIBUTE_UINT(declare, table,
+               OTM_HDMI_ATTR_ID_USE_EDID,
+               PD_ATTR_FLAGS_RWS,
+               get_name,
+               OTM_HDMI_USE_EDID_REAL,
+               OTM_HDMI_USE_EDID_NONE,
+               OTM_HDMI_USE_EDID_SAFE);
+
+       PD_DECLARE_ATTRIBUTE_UINT(declare, table,
+               OTM_HDMI_ATTR_ID_DEBUG,
+               PD_ATTR_FLAGS_RWS,
+               get_name,
+               PD_LOG_LEVEL_ERROR,
+               __PD_LOG_LEVEL_MIN, __PD_LOG_LEVEL_MAX);
+
+       PD_DECLARE_ATTRIBUTE_UINT(declare, table,
+               OTM_HDMI_ATTR_ID_VERSION_MAJOR,
+               PD_ATTR_FLAGS_RS, get_name, 0, 0, 100);
+
+       PD_DECLARE_ATTRIBUTE_UINT(declare, table,
+               OTM_HDMI_ATTR_ID_VERSION_MINOR,
+               PD_ATTR_FLAGS_RS, get_name, 4, 0, 9);
+
+       PD_DECLARE_ATTRIBUTE_STRING(declare, table,
+               OTM_HDMI_ATTR_ID_BUILD_DATE,
+               PD_ATTR_FLAGS_RS, get_name, __DATE__);
+
+       PD_DECLARE_ATTRIBUTE_STRING(declare, table,
+               OTM_HDMI_ATTR_ID_BUILD_TIME,
+               PD_ATTR_FLAGS_RS, get_name, __TIME__);
+
+       PD_DECLARE_ATTRIBUTE_UINT(declare, table,
+               OTM_HDMI_ATTR_ID_DISPLAY_PIPE,
+               PD_ATTR_FLAGS_RWS,
+               get_name,
+               OTM_HDMI_DISPLAY_ID_0,
+               OTM_HDMI_DISPLAY_ID_0,
+               OTM_HDMI_DISPLAY_ID_UNDEFINED);
+
+       PD_DECLARE_ATTRIBUTE_UINT(declare, table,
+               OTM_HDMI_ATTR_ID_PAR,
+               PD_ATTR_FLAGS_RWS,
+               get_name,
+               OTM_HDMI_PAR_NO_DATA,
+               OTM_HDMI_PAR_NO_DATA,
+               OTM_HDMI_PAR_16_9);
+
+       PD_DECLARE_ATTRIBUTE_UINT(declare, table,
+               OTM_HDMI_ATTR_ID_FAR,
+               PD_ATTR_FLAGS_RWS,
+               get_name,
+               OTM_HDMI_FAR_SAME_AS_PAR,
+               OTM_HDMI_FAR_16_9_TOP,
+               OTM_HDMI_FAR_16_9_SP_4_3);
+
+       PD_DECLARE_ATTRIBUTE_BOOL(declare, table,
+               OTM_HDMI_ATTR_ID_SLOW_DDC,
+               PD_ATTR_FLAGS_RWS, get_name, true);
+
+       PD_DECLARE_ATTRIBUTE_UINT(declare, table,
+               OTM_HDMI_ATTR_ID_AUDIO_CLOCK,
+               PD_ATTR_FLAGS_RWS,
+               get_name,
+               OTM_HDMI_AUDIO_CLOCK_36,
+               OTM_HDMI_AUDIO_CLOCK_24,
+               OTM_HDMI_AUDIO_CLOCK_16);
+
+       PD_DECLARE_ATTRIBUTE_BOOL(declare, table,
+               OTM_HDMI_ATTR_ID_AUDIO_STATUS,
+               PD_ATTR_FLAGS_RS, get_name, false);
+
+       PD_DECLARE_ATTRIBUTE_UINT(declare, table,
+               OTM_HDMI_ATTR_ID_TMDS_DELAY,
+               PD_ATTR_FLAGS_RWS, get_name, 400, 100, 500);
+
+       PD_DECLARE_ATTRIBUTE_BOOL(declare, table,
+               OTM_HDMI_ATTR_ID_COLOR_SPACE_EXT,
+               PD_ATTR_FLAGS_RWS, get_name, false);
+
+       PD_DECLARE_ATTRIBUTE_BOOL(declare, table,
+               OTM_HDMI_ATTR_ID_OUTPUT_CLAMP,
+               PD_ATTR_FLAGS_RWS, get_name, true);
+
+       PD_DECLARE_ATTRIBUTE_BOOL(declare, table,
+               OTM_HDMI_ATTR_ID_OUTPUT_DITHER,
+               PD_ATTR_FLAGS_RWS, get_name, false);
+
+       PD_DECLARE_ATTRIBUTE_BOOL(declare, table,
+               OTM_HDMI_ATTR_ID_HDCP_1P1,
+               PD_ATTR_FLAGS_RWS, get_name, true);
+
+       PD_DECLARE_ATTRIBUTE_UINT(declare, table,
+               OTM_HDMI_ATTR_ID_MUTE,
+               PD_ATTR_FLAGS_RWS,
+               get_name,
+               OTM_HDMI_MUTE_OFF,
+               OTM_HDMI_MUTE_OFF, OTM_HDMI_MUTE_BOTH);
+
+       PD_DECLARE_ATTRIBUTE_BOOL(declare, table,
+               OTM_HDMI_ATTR_ID_PURE_VIDEO,
+               PD_ATTR_FLAGS_RWS, get_name, false);
+
+       PD_DECLARE_ATTRIBUTE_BOOL(declare, table,
+               OTM_HDMI_ATTR_ID_HDCP_AUTO_PHY,
+               PD_ATTR_FLAGS_RWS, get_name, true);
+
+       PD_DECLARE_ATTRIBUTE_BOOL(declare, table,
+               OTM_HDMI_ATTR_ID_HDCP_AUTO_RETRY,
+               PD_ATTR_FLAGS_RWS, get_name, true);
+
+       PD_DECLARE_ATTRIBUTE_BOOL(declare, table,
+               OTM_HDMI_ATTR_ID_DVI,
+               PD_ATTR_FLAGS_RWS, get_name, false);
+
+       PD_DECLARE_ATTRIBUTE_UINT(declare, table,
+               OTM_HDMI_ATTR_ID_HDCP_RI_RETRY,
+               PD_ATTR_FLAGS_RWS, get_name, 40, 0, 50);
+
+       PD_LOG_EXIT(PD_LOG_LEVEL_HIGH, rc);
+       return rc;
+}
+EXPORT_SYMBOL(otm_hdmi_declare_attributes);
+
+/*
+ * Description: crtc mode set function for hdmi.
+ *
+ * @context:           hdmi_context
+ * @mode:              mode requested
+ * @adjusted_mode:     adjusted mode
+ * @fb_width, fb_height:allocated frame buffer dimensions
+ * @pclk_khz:          tmds clk value for the best pll and is needed for audio.
+ *                     This field has to be moved into OTM audio
+ *                     interfaces when implemented
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+/*
+ * TODO: Revisit scaling type enums:
+ * 0 - scale_none
+ * 1 - full screen
+ * 2 - center
+ * 3 - scale aspect
+ */
+otm_hdmi_ret_t otm_hdmi_crtc_mode_set(void *context, otm_hdmi_timing_t *mode,
+                       otm_hdmi_timing_t *adjusted_mode, int fb_width,
+                       int fb_height, uint32_t *pclk_khz)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       hdmi_context_t *ctx = (hdmi_context_t *)context;
+       int scalingtype = IPIL_TIMING_SCALE_NONE;
+
+       /* NULL checks */
+       if (context == NULL || mode == NULL || adjusted_mode == NULL
+                                               || pclk_khz == NULL) {
+               pr_debug("\ninvalid arguments\n");
+               return OTM_HDMI_ERR_INVAL;
+       }
+
+       /* prepare for crtc mode set. This includes any hdmi unit reset etc. */
+       rc = ipil_hdmi_crtc_mode_set_prepare(&ctx->dev);
+       if (rc != OTM_HDMI_SUCCESS) {
+               pr_debug("\nfailed in preparing for mode set\n");
+               return rc;
+       }
+
+       /* get the preferred scaling type for the platform */
+       rc = ps_hdmi_get_pref_scalingtype(ctx, &scalingtype);
+       if (rc != OTM_HDMI_SUCCESS) {
+               pr_debug("\nfailed to get preferred scaling type\n");
+               return rc;
+       }
+       /* TODO: For phone, these registers are taken care in
+        * pipe_set_base call. Need to combine both the solutions
+        * into a common function.
+        */
+#ifndef MFLD_HDMI_PR3
+       /* program display related registers: dpssize and pipesrc, pfit */
+       rc = ipil_hdmi_crtc_mode_set_program_dspregs(&ctx->dev, scalingtype,
+                                               mode, adjusted_mode,
+                                               fb_width, fb_height);
+       if (rc != OTM_HDMI_SUCCESS) {
+               pr_debug("\nfailed to set display registers\n");
+               return rc;
+       }
+#endif
+
+       /* program hdmi mode timing registers */
+       rc = ipil_hdmi_crtc_mode_set_program_timings(&ctx->dev,
+                                               scalingtype, mode,
+                                               adjusted_mode);
+       if (rc != OTM_HDMI_SUCCESS) {
+               pr_debug("\nfailed to set timing registers\n");
+               return rc;
+       }
+
+       /* program hdmi mode timing registers */
+       rc = ipil_hdmi_crtc_mode_set_program_dpll(&ctx->dev,
+                                               adjusted_mode->dclk);
+       if (rc != OTM_HDMI_SUCCESS) {
+               pr_debug("\nfailed to program dpll\n");
+               return rc;
+       }
+       *pclk_khz = ctx->dev.clock_khz;
+
+       /* program hdmi mode timing registers */
+       rc = ipil_hdmi_crtc_mode_set_program_pipeconf(&ctx->dev);
+       if (rc != OTM_HDMI_SUCCESS)
+               pr_debug("\nfailed to program pipeconf\n");
+
+       return rc;
+}
+
+/*
+ * Description: encoder mode set function for hdmi. enables phy.
+ *             set correct polarity for the current mode.
+ *
+ * @context:           hdmi_context
+ * @mode:              mode requested
+ * @adjusted_mode:     adjusted mode
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t otm_hdmi_enc_mode_set(void *context, otm_hdmi_timing_t *mode,
+                       otm_hdmi_timing_t *adjusted_mode)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       hdmi_context_t *ctx = (hdmi_context_t *)context;
+       bool is_monitor_hdmi;
+
+       /* NULL checks */
+       if (context == NULL || mode == NULL || adjusted_mode == NULL) {
+               pr_debug("\ninvalid arguments\n");
+               return OTM_HDMI_ERR_INVAL;
+       }
+
+       is_monitor_hdmi = otm_hdmi_is_monitor_hdmi(ctx);
+       pr_debug("\nMonitor Mode: %s\n", is_monitor_hdmi ? "HDMI" : "DVI");
+
+       /* handle encoder mode set */
+       rc = ipil_hdmi_enc_mode_set(&ctx->dev, mode, adjusted_mode,
+                                       is_monitor_hdmi);
+       if (rc != OTM_HDMI_SUCCESS) {
+               pr_debug("\nfailed in programing enc mode set\n");
+               return rc;
+       }
+
+       /* Enable AVI infoframes for HDMI mode */
+       if (is_monitor_hdmi) {
+               rc = otm_hdmi_infoframes_set_avi(context, mode);
+               if (rc != OTM_HDMI_SUCCESS)
+                       pr_debug("\nfailed to program avi infoframe\n");
+       } else {/* Disable all inofoframes for DVI mode */
+               rc = otm_hdmi_disable_all_infoframes(context);
+               if (rc != OTM_HDMI_SUCCESS)
+                       pr_debug("\nfailed to disable all infoframes\n");
+       }
+
+       return rc;
+}
+
+/*
+ * Description: restore HDMI registers and enable the display
+ *
+ * @context:   hdmi_context
+ *
+ * Returns:    none
+ */
+void otm_hdmi_restore_and_enable_display(void *context, bool connected)
+{
+       if (NULL != context) {
+               if (connected) {
+                       ipil_hdmi_restore_and_enable_display(
+                                       &((hdmi_context_t *)context)->dev);
+                       /* restore data island packets */
+                       if (otm_hdmi_is_monitor_hdmi(context)) {
+                               ipil_hdmi_restore_data_island(
+                                       &((hdmi_context_t *)context)->dev);
+                       }
+               } else {
+                       ipil_hdmi_destroy_saved_data(
+                                       &((hdmi_context_t *)context)->dev);
+               }
+#ifdef OTM_HDMI_HDCP_ENABLE
+               /* inform HDCP about resume */
+               if (otm_hdmi_hdcp_set_power_save(context, false)
+                                               == false)
+                       pr_debug("failed to resume hdcp\n");
+#endif
+       }
+}
+
+/*
+ * Description: save HDMI display registers
+ *
+ * @context:   hdmi_context
+ *
+ * Returns:    none
+ */
+void otm_hdmi_save_display_registers(void *context, bool connected)
+{
+       if (NULL != context) {
+               if (connected) {
+                       ipil_hdmi_save_display_registers(
+                                       &((hdmi_context_t *)context)->dev);
+                       /* save data island packets */
+                       if (otm_hdmi_is_monitor_hdmi(context)) {
+                               ipil_hdmi_save_data_island(
+                                       &((hdmi_context_t *)context)->dev);
+                       }
+               } else {
+                       ipil_hdmi_destroy_saved_data(
+                                       &((hdmi_context_t *)context)->dev);
+               }
+       }
+}
+
+/*
+ * Description: disable HDMI display
+ *
+ * @context:   hdmi_context
+ *
+ * Returns:    none
+ */
+void otm_disable_hdmi(void *context)
+{
+       if (NULL != context) {
+#ifdef OTM_HDMI_HDCP_ENABLE
+               /* inform HDCP about suspend */
+               if (otm_hdmi_hdcp_set_power_save(context, true)
+                                               == false)
+                       pr_debug("failed to suspend hdcp\n");
+#endif
+               /* disable HDMI */
+               ipil_disable_hdmi(&((hdmi_context_t *)context)->dev);
+       }
+}
+
+/**
+ *
+ * Internal scripts wrapper functions.
+ *
+ */
+
+/* Starting this off, but all scripts/unit test helpers should move
+ * to another file.
+ */
+
+#ifdef OTM_HDMI_UNIT_TEST
+
+/**
+ *     test_otm_hdmi_report_edid() - Report current EDID information
+ *
+ *     This routine simply dumps the EDID information
+ *
+ *     Returns - nothing
+ */
+void test_otm_hdmi_report_edid()
+{
+       edid_info_t *edid = NULL;
+       if (NULL == g_context) {
+               PD_LOG_PRINT(PD_LOG_LEVEL_HIGH,
+                            "Cant print EDID, Initialize otm_hdmi first!\n");
+               return;
+       }
+       edid = &g_context->edid_int;
+       if (NULL == edid) {
+               PD_LOG_PRINT(PD_LOG_LEVEL_HIGH,
+                            "EDID not initialized in driver.\n");
+               return;
+       }
+       __hdmi_report_edid(g_context, edid);
+}
+EXPORT_SYMBOL_GPL(test_otm_hdmi_report_edid);
+#endif
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/include/hdcp_api.h b/drivers/staging/mrst/drv/otm_hdmi/pil/include/hdcp_api.h
new file mode 100644 (file)
index 0000000..b0738cc
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef HDCP_API_H
+#define HDCP_API_H
+
+#include <linux/types.h>
+#include "hdmi_internal.h"
+
+extern bool otm_hdmi_hdcp_set_hpd_state(hdmi_context_t *hdmi_context,
+                                               bool hpd);
+extern bool otm_hdmi_hdcp_set_power_save(hdmi_context_t *hdmi_context,
+                                               bool suspend);
+extern bool otm_hdmi_hdcp_set_dpms(hdmi_context_t *hdmi_context,
+                                       bool display_power_on);
+extern bool otm_hdmi_hdcp_enable(hdmi_context_t *hdmi_context);
+extern bool otm_hdmi_hdcp_disable(hdmi_context_t *hdmi_context);
+extern bool otm_hdmi_hdcp_init(hdmi_context_t *hdmi_context,
+       int (*ddc_rd_wr)(bool, uint8_t, uint8_t, uint8_t *, int));
+
+#endif /* HDCP_API_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/include/otm_hdmi.h b/drivers/staging/mrst/drv/otm_hdmi/pil/include/otm_hdmi.h
new file mode 100644 (file)
index 0000000..5e74660
--- /dev/null
@@ -0,0 +1,358 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+       Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+       Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef _OTM_HDMI_H
+#define _OTM_HDMI_H
+
+
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+
+#include "otm_hdmi_types.h"
+#include "otm_hdmi_defs.h"
+
+/**
+ * Attribute name getting routine
+ */
+char *__pd_attr_get_name(otm_hdmi_attribute_id_t id);
+
+/**
+ * Type definition based on the function signature above
+ */
+typedef otm_hdmi_ret_t(*pd_attr_set_t)(otm_hdmi_attribute_t *table,
+                               otm_hdmi_attribute_id_t id,
+                               void *value,
+                               otm_hdmi_attribute_flag_t flags);
+
+/**
+ * Attribute name getting routine
+ */
+char *__pd_attr_get_name(otm_hdmi_attribute_id_t id);
+
+/**
+ * Type definition based on the function signature above
+ */
+typedef char *(*pd_attr_get_name_t)(otm_hdmi_attribute_id_t id);
+
+/**
+ * Attribute declaration / setting macros
+ */
+#define PD_DECLARE_ATTRIBUTE_BOOL(f_d, t, id, flags, \
+       f_n, value) \
+       f_d(t, id, OTM_HDMI_ATTR_TYPE_BOOLEAN, flags, \
+       f_n(id), (void *) value, 0, 0)
+
+#define PD_DECLARE_ATTRIBUTE_BOOL_CUSTOM(f_d, t, id, flags, \
+       name, value) \
+       f_d(t, id, OTM_HDMI_ATTR_TYPE_BOOLEAN, flags, \
+       name, (void *) value, 0, 0)
+
+#define PD_DECLARE_ATTRIBUTE_UINT(f_d, t, id, flags, \
+       f_n, value, min, max) \
+       f_d(t, id, OTM_HDMI_ATTR_TYPE_UINT, flags, \
+       f_n(id), (void *) value, min, max)
+
+#define PD_DECLARE_ATTRIBUTE_UINT_CUSTOM(f_d, t, id, flags, \
+       name, value, min, max) \
+       f_d(t, id, OTM_HDMI_ATTR_TYPE_UINT, flags, \
+       name, (void *) value, min, max)
+
+#define PD_DECLARE_ATTRIBUTE_STRING(f_d, t, id, \
+       flags, f_n, value) \
+       f_d(t, id, OTM_HDMI_ATTR_TYPE_STRING, flags, \
+       f_n(id), (void *) value, 0, 0)
+
+#define PD_DECLARE_ATTRIBUTE_STRING_CUSTOM(f_d, t, id, \
+       flags, name, value) \
+       f_d(t, id, OTM_HDMI_ATTR_TYPE_STRING, flags,    \
+       name, (void *) value, 0, 0)
+
+/**
+ * Attribute values accessor macros
+ */
+#define PD_ATTR_BOOL(attr) ((attr).content._bool.value)
+#define PD_ATTR_UINT(attr) ((attr).content._uint.value)
+
+/**
+ * Shortcuts for common flags combinations
+ */
+#define PD_ATTR_FLAGS_RWSI (OTM_HDMI_ATTR_FLAG_WRITE | \
+                       OTM_HDMI_ATTR_FLAG_SUPPORTED | \
+                       OTM_HDMI_ATTR_FLAG_INTERNAL)
+
+#define PD_ATTR_FLAGS_RWS (OTM_HDMI_ATTR_FLAG_WRITE | \
+                       OTM_HDMI_ATTR_FLAG_SUPPORTED)
+
+#define PD_ATTR_FLAGS_RS (OTM_HDMI_ATTR_FLAG_SUPPORTED)
+
+/**
+ * Display timing information
+ */
+typedef struct {
+       unsigned short width;           /* width                            */
+       unsigned short height;          /* height                           */
+       otm_hdmi_refresh_t refresh;     /* refresh rate                     */
+       unsigned long dclk;             /* refresh rate dot clock in kHz    */
+       unsigned short htotal;          /* horizontal total                 */
+       unsigned short hblank_start;    /* horizontal blank start           */
+       unsigned short hblank_end;      /* horizontal blank end             */
+       unsigned short hsync_start;     /* horizontal sync start            */
+       unsigned short hsync_end;       /* horizontal sync end              */
+       unsigned short vtotal;          /* vertical total                   */
+       unsigned short vblank_start;    /* vertical blank start             */
+       unsigned short vblank_end;      /* vertical blank end               */
+       unsigned short vsync_start;     /* vertical sync start              */
+       unsigned short vsync_end;       /* vertical sync end                */
+       unsigned long mode_info_flags;  /* flags                            */
+       otm_hdmi_stereo_t stereo_type;  /* stereo mode type                 */
+       unsigned long metadata;         /* port driver specific information */
+} otm_hdmi_timing_t;
+
+/* set timing from cea modes */
+int otm_hdmi_timing_from_cea_modes(unsigned char *buffer,
+                                  otm_hdmi_timing_t *pdts);
+
+/* get timings of a mode */
+otm_hdmi_timing_t *otm_hdmi_get_mode_timings(void *context,
+                                       int hdisplay,
+                                       int vdisplay,
+                                       int vrefresh);
+
+/* parse the raw edid and fill the capability table */
+otm_hdmi_ret_t otm_hdmi_edid_parse(void *ctx, otm_hdmi_use_edid_t use_edid);
+
+/* install HPD IRQ */
+otm_hdmi_ret_t otm_hdmi_setup_irq(void *context, struct pci_dev *pdev,
+                               irqreturn_t (*phdmi_irq_cb) (int, void*),
+                               void *data);
+
+/* init hdmi device driver */
+otm_hdmi_ret_t otm_hdmi_device_init(void **context, struct pci_dev *pdev);
+
+/* read edid information */
+unsigned char *otm_hdmi_read_edid(void);
+
+/* turn HDMI power rails on */
+bool otm_hdmi_power_rails_on();
+
+/* get pixel clock range */
+otm_hdmi_ret_t otm_hdmi_get_pixel_clock_range(unsigned int *pc_min,
+                                       unsigned int *pc_max);
+
+/*
+ *  Getting given attribute
+ *  @param [in ] id      : attribute id
+ *  @param [out] data    : user provided buffer for attribute details
+ *  @param [in ] log     : a hint wether port driver should log the call
+ */
+otm_hdmi_ret_t otm_hdmi_get_attribute(void *context,
+                                       otm_hdmi_attribute_id_t id,
+                                       otm_hdmi_attribute_t *attribute,
+                                       bool log);
+
+/*
+ * Setting given attribute
+ * @param [in] context : port driver specific information
+ * @param [in] id       : attribute id
+ * @param [in] data     : user provided buffer with attribute value
+ * @param [in] internal : internal [driver] or external [app] call
+ */
+otm_hdmi_ret_t otm_hdmi_set_attribute(void *context,
+                                       otm_hdmi_attribute_id_t id,
+                                       void *data,
+                                       bool internal);
+
+/* check the mode is preferred or not */
+bool otm_hdmi_is_preferred_mode(int hdisplay,
+                                       int vdisplay, int refresh);
+
+/* set the raw edid into HDMI context */
+otm_hdmi_ret_t otm_hdmi_set_raw_edid(void *context, char *raw_edid);
+
+/* get the raw edid from HDMI context */
+otm_hdmi_ret_t otm_hdmi_get_raw_edid(void *context, char **raw_edid);
+
+/* check the connection is hdmi or dvi */
+bool otm_hdmi_is_monitor_hdmi(void *context);
+
+/*
+ * Description: crtc mode set function for hdmi.
+ *
+ * @context:           hdmi_context
+ * @mode:              mode requested
+ * @adjusted_mode:     adjusted mode
+ * @fb_width, fb_height:allocated frame buffer dimensions
+ * @pclk_khz:          tmds clk value for the best pll and is needed for audio.
+ *                     This field has to be moved into OTM audio
+ *                     interfaces when implemented
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t otm_hdmi_crtc_mode_set(void *context, otm_hdmi_timing_t *mode,
+                       otm_hdmi_timing_t *adjusted_mode, int fb_width,
+                       int fb_height, uint32_t *pclock_khz);
+
+/*
+ * Description: encoder mode set function for hdmi. enables phy.
+ *             set correct polarity for the current mode.
+ *
+ * @context:           hdmi_context
+ * @mode:              mode requested
+ * @adjusted_mode:     adjusted mode
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t otm_hdmi_enc_mode_set(void *context, otm_hdmi_timing_t *mode,
+                       otm_hdmi_timing_t *adjusted_mode);
+
+/*
+ * Description: save hdmi display registers
+ *
+ * @context:   hdmi_context
+ *
+ * Returns:    none
+ */
+void otm_hdmi_save_display_registers(void *context, bool connected);
+
+/*
+ * Description: disable HDMI display
+ *
+ * @context:   hdmi_context
+ *
+ * Returns:    none
+ */
+void otm_disable_hdmi(void *context);
+
+/*
+ * Description: restore hdmi display registers and enable the display
+ *
+ * @context:   hdmi_context
+ *
+ * Returns:    none
+ */
+void otm_hdmi_restore_and_enable_display(void *context, bool connected);
+
+/* TODO: Need refactor the logging and attr table */
+
+/*
+ * Logging macros
+ */
+#define ATTRIBUTES otm_hdmi_attributes_table
+
+typedef enum {
+       PD_LOG_LEVEL_ERROR = 0, /* Error messages; Will always be printed */
+       __PD_LOG_LEVEL_MIN = PD_LOG_LEVEL_ERROR,
+       /* Add log levels below this line */
+       PD_LOG_LEVEL_HIGH = 1,  /* Printed if 'debug' is set to 1 or higher */
+       PD_LOG_LEVEL_LOW,       /* Printed if 'debug' is set to 2 or higher */
+       PD_LOG_LEVEL_VBLANK,    /* Printed if 'debug' at highest level */
+       /* Add log levels above this line */
+       __PD_LOG_LEVEL_TEMP_UPPER__,    /* DO NOT USE */
+       __PD_LOG_LEVEL_MAX = __PD_LOG_LEVEL_TEMP_UPPER__ - 1,
+} pd_log_level_t;
+
+/* Used to log entry in to a function */
+#define PD_LOG_ENTRY(log_level) \
+       if ((log_level) <= (int) PD_ATTR_UINT( \
+                                       ATTRIBUTES[OTM_HDMI_ATTR_ID_DEBUG])) \
+               printk("OTM_HDMI: Entering %s\n", __func__)
+
+/* Used to log exit from a function */
+#define PD_LOG_EXIT(log_level, rc) \
+       if ((log_level) <= (int) PD_ATTR_UINT( \
+                                       ATTRIBUTES[OTM_HDMI_ATTR_ID_DEBUG])) \
+               printk("OTM_HDMI: Exiting %s with %d\n", __func__, rc)
+
+#ifdef OTM_HDMI_FIXME
+#define PD_LOG_PRINT(log_level, args...) \
+       if ((log_level) <= (int) PD_ATTR_UINT( \
+                                       ATTRIBUTES[OTM_HDMI_ATTR_ID_DEBUG])) \
+               printk(args)
+#else
+#define PD_LOG_PRINT(log_level, args...) printk("OTM_HDMI: " args)
+#endif
+
+#define PD_LOG_ERROR(msg, args...) PD_LOG_PRINT(PD_LOG_LEVEL_ERROR, msg, ##args)
+
+/*
+ * Bits in 'mode_info_flags' field
+ */
+#define PD_SCAN_INTERLACE     0x80000000 /* Interlaced pipe configuration     */
+#define PD_PIXEL_REPLICATION  0x40000000 /* Mode uses pixel replication       */
+#define PD_HSYNC_HIGH         0x20000000 /* HSYNC is active high              */
+#define PD_VSYNC_HIGH         0x10000000 /* VSYNC is active high              */
+#define PD_CLOCK_OVERSAMPLE   0x00020000 /* Indicates dot clock is a multiple */
+                                        /* of the MDVO clock; See VDC_SetMode*/
+#define PD_EVO_DITHER         0x00008000 /* Enable EVO dithering              */
+#define PD_EVO_FORMAT_8       0x00004000 /* Set EVO 8 bit mode                */
+#define PD_EVO_CLK_INV        0x00002000 /* Invert EVO pixel clock            */
+#define PD_WSS_WORKAROUND     0x00000800 /* PAL Wide Screen Signal workaround */
+#define PD_DTV_MODE           0x00000400 /* Digital Panel mode                */
+#define PD_SVBI               0x00000010 /* Software VBI supported timings    */
+#define PD_AR_16_BY_9         0x00000001 /* 16:9 aspect ratio                 */
+
+#endif /* _OTM_HDMI_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/include/otm_hdmi_defs.h b/drivers/staging/mrst/drv/otm_hdmi/pil/include/otm_hdmi_defs.h
new file mode 100644 (file)
index 0000000..030f662
--- /dev/null
@@ -0,0 +1,1167 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifndef _OTM_HDMI_DEFS_H
+#define _OTM_HDMI_DEFS_H
+
+
+#include <linux/types.h>
+
+#include "otm_hdmi_types.h"
+
+/**
+ Existing port driver IDs with room for user specified port drivers.
+ When communicating with a specific port driver the port id must be passed.
+*/
+typedef enum {
+       OTM_HDMI_MIN_SUPPORTED_DRIVERS = 0, /* Port Driver IDs start at this
+                                               value */
+
+       OTM_HDMI_ID_INTTVENC = OTM_HDMI_MIN_SUPPORTED_DRIVERS, /* CVBS TV
+                                                               encoder */
+       OTM_HDMI_ID_INTTVENC_COMPONENT, /* Component TV encoder */
+       OTM_HDMI_ID_HDMI,               /* HDMI */
+       OTM_HDMI_ID_USER_MIN,   /* Begin user defined drivers */
+       OTM_HDMI_ID_USER_MAX = 8,       /* End user defined drivers */
+
+       OTM_HDMI_MAX_SUPPORTED_DRIVERS  /* Maximum number of port drivers. */
+} otm_hdmi_id_t;
+
+/**
+Defined port driver attributes.  Which ones are supported (and exactly how)
+can vary from one port driver to another.  See the Intel� CE Media Processors
+GDL 3.0 Programming Guide for details on the attributes supported by
+each port driver.
+
+The following Attributes require "elevated" privileges:
+OTM_HDMI_ATTR_ID_HDCP
+OTM_HDMI_ATTR_ID_HDCP_AUTO_MUTE
+OTM_HDMI_ATTR_ID_POWER
+OTM_HDMI_ATTR_ID_MUTE
+OTM_HDMI_ATTR_ID_HDCP_AUTO_PHY
+OTM_HDMI_ATTR_ID_HDCP_AUTO_RETRY
+OTM_HDMI_ATTR_ID_HDCP_RI_RETRY
+OTM_HDMI_ATTR_ID_HDCP_1P1
+OTM_HDMI_ATTR_ID_HDCP_ENCRYPT
+*/
+
+/* *NOTE* Extend pd_lib.c::__pd_attr_get_name() when adding new entries */
+typedef enum {
+       OTM_HDMI_MIN_SUPPORTED_ATTRIBUTES = 0,  /* Attribute ID enum's start
+                                               at this value */
+
+       OTM_HDMI_ATTR_ID_HDCP = OTM_HDMI_MIN_SUPPORTED_ATTRIBUTES, /* HDCP
+                                                               control */
+       OTM_HDMI_ATTR_ID_HDCP_AUTO_MUTE, /* HDCP auto mute */
+       OTM_HDMI_ATTR_ID_HDCP_STATUS, /*HDCP status */
+       OTM_HDMI_ATTR_ID_HDCP_1P1, /* HDCP 1.1 Pj check control */
+       OTM_HDMI_ATTR_ID_COLOR_SPACE_INPUT, /*Input colorspace */
+       OTM_HDMI_ATTR_ID_PIXEL_FORMAT_OUTPUT, /* Output colorspace */
+       OTM_HDMI_ATTR_ID_PIXEL_DEPTH, /* Depth of outgoing pixels */
+       OTM_HDMI_ATTR_ID_BG_COLOR, /* Color for HDCP failure & video mute */
+       OTM_HDMI_ATTR_ID_CABLE_STATUS, /* Cable status */
+       OTM_HDMI_ATTR_ID_PAR, /* Picture aspect ratio */
+       OTM_HDMI_ATTR_ID_FAR, /* Format aspect ratio */
+       OTM_HDMI_ATTR_ID_USE_EDID, /* TV timings source */
+       OTM_HDMI_ATTR_ID_SLOW_DDC, /* DDC bus speed */
+       OTM_HDMI_ATTR_ID_AUDIO_CLOCK, /* Audio clock */
+       OTM_HDMI_ATTR_ID_COLOR_SPACE_EXT, /* Extended colorimetry */
+       OTM_HDMI_ATTR_ID_OUTPUT_CLAMP, /* Clamp output in [16,235] when it is */
+       /* RGB color space. In YCbCr output */
+       /* this attribute is ignored. */
+       OTM_HDMI_ATTR_ID_BRIGHTNESS, /* Brightness Level */
+       OTM_HDMI_ATTR_ID_CONTRAST, /* Contrast Level */
+       OTM_HDMI_ATTR_ID_HUE, /* Hue Angle */
+       OTM_HDMI_ATTR_ID_SATURATION, /* Saturation Level */
+       OTM_HDMI_ATTR_ID_ACP, /* Analog Content Protection */
+       OTM_HDMI_ATTR_ID_CC, /* Closed Captioning */
+       OTM_HDMI_ATTR_ID_OUTPUT_DITHER, /* Dither 12-bit->10/8bit conversion */
+       OTM_HDMI_ATTR_ID_SHARPNESS_HLUMA, /* Horizontal Luma filter */
+       OTM_HDMI_ATTR_ID_SHARPNESS_HCHROMA, /* Horizontal Chroma Filter */
+       OTM_HDMI_ATTR_ID_BLANK_LEVEL, /* Sync pulse level */
+       OTM_HDMI_ATTR_ID_BLACK_LEVEL, /* Black Level */
+       OTM_HDMI_ATTR_ID_BURST_LEVEL, /* Burst Level */
+       OTM_HDMI_ATTR_ID_HDCP_RI_RETRY, /* RI retry delay */
+       OTM_HDMI_ATTR_ID_DVI,   /* DVI enforcement */
+       OTM_HDMI_ATTR_ID_TVOUT_TYPE, /* Current DAC configuration */
+       OTM_HDMI_ATTR_ID_HDCP_ENCRYPT, /* HDCP encryption control */
+       OTM_HDMI_ATTR_ID_3CH_SYNC, /* 3 Channel sync */
+       OTM_HDMI_ATTR_ID_SD_OPTION, /* Alternate SD mode (e.g.: PAL-M, */
+       /* PAL-N, etc.) */
+       OTM_HDMI_ATTR_ID_RGB,   /* RGB / YPbPr output selection */
+       OTM_HDMI_ATTR_ID_CGMS_MODE, /* Current Copy Generation mode */
+       OTM_HDMI_ATTR_ID_NO_SYNC, /* Sync removal from green (y) signal */
+       OTM_HDMI_ATTR_ID_YC_DELAY, /* Luma vs Chroma delay */
+       OTM_HDMI_ATTR_ID_POWER, /* Disable DAC output */
+       OTM_HDMI_ATTR_ID_NAME,  /* Driver name */
+       OTM_HDMI_ATTR_ID_VERSION_MAJOR, /* Driver major version */
+       OTM_HDMI_ATTR_ID_VERSION_MINOR, /* Driver minor version */
+       OTM_HDMI_ATTR_ID_DEBUG, /* Debug log */
+       OTM_HDMI_ATTR_ID_BUILD_DATE, /* Driver Build date */
+       OTM_HDMI_ATTR_ID_BUILD_TIME, /* Driver Build time */
+       OTM_HDMI_ATTR_ID_DISPLAY_PIPE, /* Display Pipeline assigned */
+       OTM_HDMI_ATTR_ID_SVIDEO, /* Assignment of component Pb & Pr */
+       /* DACs for S-Video output */
+       OTM_HDMI_ATTR_ID_AUDIO_STATUS, /* Status of audio playback */
+       OTM_HDMI_ATTR_ID_TMDS_DELAY, /* HPD to TMDS assert delay */
+       OTM_HDMI_ATTR_ID_MUTE, /* Mute */
+       OTM_HDMI_ATTR_ID_PURE_VIDEO, /* Pure video indication control */
+       OTM_HDMI_ATTR_ID_HDCP_AUTO_PHY, /* PHY blinking on HDCP Ri/Pj failure */
+       OTM_HDMI_ATTR_ID_CALIBRATION, /* Calibration value */
+       OTM_HDMI_ATTR_ID_HDCP_AUTO_RETRY, /* Automatic HDCP retry control */
+       OTM_HDMI_ATTR_ID_INTERNAL_TEST, /* CVBS/Component internal test */
+
+       /* EXTENDED */
+       OTM_HDMI_ATTR_ID_USER_MIN, /* Start of user defined attributes */
+       OTM_HDMI_ATTR_ID_USER_MAX = 100, /* Max user defined attribute */
+       OTM_HDMI_MAX_SUPPORTED_ATTRIBUTES /* End of attribute IDs;
+                                               must be last */
+} otm_hdmi_attribute_id_t;
+
+
+/*
+ * the following def should be moved to otm_htmi_internel.h later
+ */
+#define PD_NAME "pd_hdmi"
+
+/** @ingroup disp_mode
+ * Defines supported color spaces
+ *
+ */
+typedef enum {
+       /* Normally used for Standard Definition YCbCr content */
+       OTM_HDMI_COLOR_SPACE_BT601 = 0,
+       /* Normally used for High Definition YCbCr content */
+       OTM_HDMI_COLOR_SPACE_BT709,
+       /* Used for all RGB pixel formats */
+       OTM_HDMI_COLOR_SPACE_RGB,
+       /* Number of entries in this enumeration */
+       OTM_HDMI_COLOR_SPACE_COUNT
+} otm_hdmi_color_space_t;
+
+/** @ingroup disp_mode
+ * Display (pipe) ids.  The Intel CE Media Processors have two displays.
+ */
+typedef enum {
+       /* [Pipe A] Main display/HDMI */
+       OTM_HDMI_DISPLAY_ID_0 = 0,
+       /* [Pipe B] Secondary display/Composite */
+       OTM_HDMI_DISPLAY_ID_1,
+       /* Undefined Pipe */
+       OTM_HDMI_DISPLAY_ID_UNDEFINED
+} otm_hdmi_display_id_t;
+
+/*
+ *
+ * Attribute usage flags.
+ */
+/* TODO: Move OTM_HDMI_ATTR_FLAG_SUPPORTED since it's internal to PD */
+typedef enum {
+       OTM_HDMI_ATTR_FLAG_WRITE = 0x1, /* Attribute can be written */
+       OTM_HDMI_ATTR_FLAG_SUPPORTED = 0x2,
+                                     /* Attribute is supported on this port
+                                       driver. FOR INTERNAL USE ONLY. */
+       OTM_HDMI_ATTR_FLAG_INTERNAL = 0x4,
+                                     /* Attribute is invisible to outside
+                                       world. FOR INTERNAL USE ONLY */
+} otm_hdmi_attribute_flag_t;
+
+/*
+ * Attribute flags used internally to override / extend certain behavior
+ * NOTE: Make sure values don't collide with otm_hdmi_attribute_flag_t
+ */
+#define OTM_HDMI_ATTR_FLAG_FORCED 0x8000 /* Read only is ignored */
+
+/**
+    Attribute types
+*/
+typedef enum {
+       OTM_HDMI_ATTR_TYPE_UINT, /* Attribute is of type #unsigned int. */
+       OTM_HDMI_ATTR_TYPE_BOOLEAN, /* Attribute is of type #bool. */
+       OTM_HDMI_ATTR_TYPE_STRING /* Attribute is a read-only 0-terminated
+                                       ASCII string. */
+} otm_hdmi_attribute_type_t;
+
+/**
+   Maximum size of PD string attributes
+*/
+#define OTM_HDMI_MAX_STRING_LENGTH 16
+
+/**
+     This structure represents port driver attribute
+*/
+typedef struct {
+       otm_hdmi_attribute_id_t id;     /* Global attribute ID. */
+       otm_hdmi_attribute_type_t type; /* Data type of attribute. */
+       otm_hdmi_attribute_flag_t flags;/* Access permissions and
+                                               internal use*/
+
+       char name[OTM_HDMI_MAX_STRING_LENGTH + 1];
+
+       union   /* Attribute data dependent on attribute type */
+       {
+               struct {
+                       unsigned int value_default; /* default value */
+                       unsigned int value_min; /* minimum value */
+                       unsigned int value_max; /* maximum value */
+                       unsigned int value;     /* current value */
+               } _uint;
+
+               struct {
+                       bool value_default; /* default value */
+                       bool value; /* current value */
+               } _bool;
+
+               struct {
+                       /* current value */
+                       char value[OTM_HDMI_MAX_STRING_LENGTH + 1];
+               } string;
+
+       } content;
+} otm_hdmi_attribute_t;
+
+/**
+    The Internal TV Encoders can support several different TV standards when
+    they are used in Standard Definition (SD) resolutions.  The entries in
+    this enumeration are values that can be used to set the
+    OTM_HDMI_ATR_ID_SD_OPTION attribute to specify the standard to be used
+    for SD.
+*/
+typedef enum {
+       TV_STD_UNDEFINED = 0, /* Use Default per resolution */
+       TV_STD_NTSC = 0, /* Use NTSC for 720x480i mode. */
+       TV_STD_PAL = 0,  /* Use PAL for 720x576i mode. */
+       TV_STD_NTSC_J = 1, /* Use NTSC-J (Japan) for 720x480i mode. */
+       TV_STD_PAL_M = 2, /* Use PAL-M (Brazil) for 720x480i mode. */
+       TV_STD_PAL_N = 3, /* Use PAL-N (Argentina) for 720x576i mode. */
+       TV_STD_MAX /* The number of IDs in this enumeration. */
+} otm_hdmi_sd_option_t;
+
+/*
+ * Unique IDs for [end user -> port driver] communication
+ */
+/*
+ * Command codes for the otm_hdmi_port_send() function.
+ */
+typedef enum {
+       OTM_HDMI_SEND_CC = 0,
+       /* Closed Captioning data; see #otm_hdmi_cc_data_t */
+       OTM_HDMI_SEND_PAL_WSS,
+       /* Pal Wide Screen signaling; See #otm_hdmi_wss_data_t */
+       OTM_HDMI_SEND_CGMS_A,
+       /* CGMS-A for NTSC and ATSC formats; See #otm_hdmi_cgms_data_t */
+       OTM_HDMI_SEND_CGMS_A_TYPE_B,
+       /* CGMS-A for CEA 770.2 and 770.3; see #otm_hdmi_cgms_type_b_data_t */
+       OTM_HDMI_SEND_HDMI_AUDIO_CTRL,
+       /* HDMI audio data; See #otm_hdmi_audio_ctrl_t */
+       OTM_HDMI_SEND_HDMI_HDCP_SRM,
+       /* HDCP System Renewability Message */
+       OTM_HDMI_SEND_HDMI_PACKET,
+       /* Generic HDMI packet; See #otm_hdmi_packet_info_t */
+       OTM_HDMI_SEND_HDMI_PHY,
+       /* Set HDMI PHY electrical properties */
+       OTM_HDMI_SEND_TELETEXT,
+       /* Teletext data to be re inserted into the vbi */
+       OTM_HDMI_SEND_USER_MIN,
+       /* External (non-Intel) port drivers may define command codes
+               starting with this value.
+       */
+       OTM_HDMI_SEND_USER_MAX = 30
+       /* External (non-Intel) port drivers may define command codes up to
+               this value.
+       */
+} otm_hdmi_otm_hdmi_send_t;
+
+/* Unique IDs for [port driver -> end user] communication */
+/**
+    Command codes for retrieving port driver extended information
+    via otm_hdmi_port_recv().
+*/
+typedef enum {
+       OTM_HDMI_RECV_HDMI_AUDIO_CTRL = 0, /* Audio control information
+                                       see #otm_hdmi_audio_ctrl_t       */
+       OTM_HDMI_RECV_HDMI_SINK_INFO,  /* HDMI sink information
+                                       see #otm_hdmi_sink_info_t        */
+       OTM_HDMI_RECV_HDMI_EDID_BLOCK, /* 128 bytes of raw EDID
+                                       see #otm_hdmi_edid_block_t       */
+       OTM_HDMI_RECV_HDMI_HDCP_INFO,  /* HDCP information        */
+       OTM_HDMI_RECV_HDMI_HDCP_KSVS,  /* HDCP keys selection vectors      */
+       OTM_HDMI_RECV_HDMI_PHY,      /* PHY settings                     */
+       OTM_HDMI_RECV_HDMI_NATIVE_MODE,/* Native modes query               */
+       OTM_HDMI_RECV_USER_MIN,      /* Begin user defined command codes */
+       OTM_HDMI_RECV_USER_MAX = 30    /* End user defined command codes   */
+} otm_hdmi_otm_hdmi_receive_t;
+
+/* Output pixel format */
+/**
+    Attribute values for the HDMI output pixel format.
+    See #OTM_HDMI_ATTR_ID_PIXEL_FORMAT_OUTPUT.
+*/
+typedef enum {
+       OTM_HDMI_OPF_RGB444 = 0,        /* RGB 4:4:4 Output */
+       OTM_HDMI_OPF_YUV422,    /* YUV 4:2:2 Output */
+       OTM_HDMI_OPF_YUV444,    /* YUV 4:4:4 Output */
+       OTM_HDMI_OPF_COUNT      /* Number of output pixel formats + 1 */
+} otm_hdmi_output_pixel_format_t;
+
+/* Output pixel depth */
+/**
+    Attribute values for the HDMI output pixel depth.
+    See #OTM_HDMI_ATTR_ID_PIXEL_DEPTH.
+*/
+typedef enum {
+       OTM_HDMI_OPD_24BIT = 0, /* 24 bits per pixel */
+       OTM_HDMI_OPD_30BIT,     /* 30 bits per pixel */
+       OTM_HDMI_OPD_36BIT,     /* 36 bits per pixel */
+       OTM_HDMI_PIXEL_DEPTH_COUNT /* Number of supported pixel depths + 1 */
+} otm_hdmi_output_pixel_depth_t;
+
+/* Picture Aspect Ratio infoframe code */
+/**
+    Attribute values for the HDMI Picture Aspect Ratio information sent via
+    AVI infoframes. See #OTM_HDMI_ATTR_ID_PAR .
+*/
+typedef enum {
+       OTM_HDMI_PAR_NO_DATA = 0x00,    /* No aspect ratio specified */
+       OTM_HDMI_PAR_4_3 = 0x01,        /* 4:3 aspect ratio */
+       OTM_HDMI_PAR_16_9 = 0x02,       /* 16:9 aspect ratio */
+} otm_hdmi_par_t;
+
+/* Format Aspect Ratio infoframe code */
+/**
+    Attribute values for the HDMI Format Aspect Ratio information sent via
+    AVI infoframes. See #OTM_HDMI_ATTR_ID_FAR.
+*/
+typedef enum {
+       OTM_HDMI_FAR_16_9_TOP = 0x02, /* box 16:9 (top) */
+       OTM_HDMI_FAR_14_9_TOP = 0x03, /* box 14:9 (top) */
+       OTM_HDMI_FAR_G_14_9_CENTER = 0x04, /* box > 16:9 (center) */
+       OTM_HDMI_FAR_SAME_AS_PAR = 0x08, /* As encoded frame */
+       OTM_HDMI_FAR_4_3_CENTER = 0x09, /* 4:3 center */
+       OTM_HDMI_FAR_16_9_CENTER = 0x0A, /* 16:9 center */
+       OTM_HDMI_FAR_14_9_CENTER = 0x0B, /* 14:9 center */
+       OTM_HDMI_FAR_4_3_SP_14_9 = 0x0D, /* 4:3 with s&p 14:9 center */
+       OTM_HDMI_FAR_16_9_SP_14_9 = 0x0E, /* 16:9 with s&p 14:9 center */
+       OTM_HDMI_FAR_16_9_SP_4_3 = 0x0F, /* 4:3 with s&p 4:3 center */
+} otm_hdmi_far_t;
+
+/* V B I   S E R V I C E S */
+/**
+    When inserting VBI information into the analog TV signal, this enumeration
+    is used to indicate the field into which the information should be inserted.
+*/
+typedef enum {
+       VBI_FIELD_ID_ODD = 1,   /* Odd field (field 1).   */
+       VBI_FIELD_ID_EVEN = 2,  /* Even field (field 2).  */
+       VBI_FIELD_ID_UNDEFINED = 3
+                               /* This value should be passed when the
+                               display is in a progressive (frame) mode.
+                               */
+} otm_hdmi_vbi_fieldid_t;
+
+/**
+
+    This enumeration is used to specify values for the #OTM_HDMI_ATTR_ID_ACP
+    attribute (the Analog Copy Protection mode).
+*/
+typedef enum {
+       ACP_MODE_OFF,           /* ACP Off */
+       ACP_MODE_PSP,           /* Pseudo Sync Pulse+No Color Stripes */
+       ACP_MODE_PSP_CS_2_LINES, /* Pseudo Sync Pulse+Color Stripes (2 lines)*/
+       ACP_MODE_PSP_CS_4_LINES, /* Pseudo Sync Pulse+Color Stripes (4 lines)*/
+       ACP_MODE_PSP_ALT, /* Pseudo Sync Pulse + No Color Stripes */
+       /* Type 1 Supplement 1 BPP configuration */
+       ACP_MODE_PSP_CS_2_LINES_ALT,    /* Pseudo Sync Pulse +
+                                               Color Stripes (2 lines) */
+       /* Type 2 Supplement 1 BPP configuration */
+       ACP_MODE_PSP_CS_4_LINES_ALT     /* Pseudo Sync Pulse +
+                                               Color Stripes (4 lines) */
+           /* Type 3 Supplement 1 BPP configuration */
+} otm_hdmi_acp_mode_t;
+
+/**
+    This enumeration specifies values for CGMS-A copy permission states to be
+    inserted into the analog TV signal. See the #otm_hdmi_cgms_data_t
+    data structure.
+*/
+typedef enum {
+       CGMS_A_COPY_FREELY = 1, /* Unlimited Copies can be made */
+       CGMS_A_COPY_NOMORE = 2, /* Copy has already been made (was reserved) */
+       CGMS_A_COPY_ONCE = 3,   /* One copy can be made */
+       CGMS_A_COPY_NEVER = 4,  /* No copies can be made */
+       CGMS_A_NO_DATA = 5      /* No data. Word 1 will be 1111 */
+} otm_hdmi_cgms_copy_t;
+
+/**
+
+    This enumeration specifies values for CGMS-A aspect ratios to be inserted
+    into the analog TV signal. See the #otm_hdmi_cgms_data_t data structure.
+*/
+typedef enum {
+       CGMS_A_4_3 = 1,  /* Normal 4:3 aspect ratio */
+       CGMS_A_4_3_LB = 2, /* 4:3 aspect ratio letterboxed */
+       CGMS_A_16_9 = 3  /* 16:9 aspect ratio (Not available at 480i/576i) */
+} otm_hdmi_cgms_aspect_t;
+
+/**
+
+    This enumeration specifies values for CGMS-A aspect ratios to be inserted
+    into the analog TV signal. See the #otm_hdmi_cgms_data_t data structure.
+*/
+typedef enum {
+       CGMS_A_SCAN_NODATA = 0, /* No Data */
+       CGMS_A_SCAN_OVER = 1,   /* Overscanned */
+       CGMS_A_SCAN_UNDER = 2,  /* Underscanned */
+       CGMS_A_SCAN_RESERVED = 3
+} otm_hdmi_cgms_scan_t;
+
+/**
+
+    This enumeration specifies values for CGMS-A aspect ratios to be inserted
+    into the analog TV signal. See the #otm_hdmi_cgms_data_t data structure.
+*/
+typedef enum {
+       CGMS_A_CSC_NO_DATA = 0, /* No Data */
+       CGMS_A_CSC_BT601 = 1,   /* BT601 */
+       CGMS_A_CSC_BT709 = 2,   /* BT709 */
+       CGMS_A_CSC_RESERVED = 3 /* Reserved */
+} otm_hdmi_cgms_colorimetery;
+
+/**
+    This enumeration specifies values for Wide Screen Signalling aspect ration
+    information to be inserted into the analog TV signal. See the
+
+*/
+typedef enum {
+       /* PAL specific Modes */
+       WSS_4_3_FF = 0,         /* 4:3 Full Format */
+       WSS_14_9_LB_C = 1,      /* 14:9 Letterbox, Centered */
+       WSS_14_9_LB_T = 2,      /* 14:9 Letterbox, Top */
+       WSS_16_9_LB_C = 3,      /* 16:9 Letterbox, Centered */
+       WSS_16_9_LB_T = 4,      /* 16:9 Letterbox, Top */
+       WSS_G_16_9_LB_C = 5,    /* 16:9 Letterbox, Centered */
+       WSS_14_9_FF = 6,        /* 14:9 Full Format */
+       WSS_16_9_ANAMORPHIC = 7, /*16:9 Anamorphic */
+} otm_hdmi_wss_aspect_t;
+
+/**
+    This enumeration specifies values for Wide Screen Signalling camera mode
+    information to be inserted into the analog TV signal. See the
+
+*/
+typedef enum {
+       WSS_CAMERA_MODE = 0,    /* Camera Mode */
+       WSS_FILM_MODE = 1,      /* Film Mode */
+} otm_hdmi_wss_camera_t;
+
+/**
+    This enumeration specifies values for Wide Screen Signalling color encoding
+    information to be inserted into the analog TV signal. See the
+
+*/
+typedef enum {
+       WSS_CE_NORMAL_PAL = 10, /* Normal PAL Colors */
+       WSS_CE_COLOR_PLUS = 11, /* Motion Adaptive Color Plus */
+} otm_hdmi_wss_ce_t;
+
+/**
+    This enumeration specifies values to indicate  Wide Screen Signalling
+    helpers state, to be inserted into the analog TV signal. See the
+
+*/
+typedef enum {
+       WSS_HELPERS_NOT_PRESENT = 1,    /* No Helper */
+       WSS_HELPERS_PRESENT = 2,        /* Modulated helper */
+
+} otm_hdmi_wss_helpers_t;
+
+/**
+    This enumeration specifies values for Wide Screen Signalling open subtitles
+    state, to be inserted into the analog TV signal.
+    See the #otm_hdmi_wss_data_t data structure.
+*/
+typedef enum {
+       WSS_OPEN_SUBTITLES_NO = 1,      /* No open subtitles */
+       WSS_OPEN_SUBTITLES_INSIDE = 2,  /* Subtitles in active image area*/
+       WSS_OPEN_SUBTITLES_OUTSIDE = 3, /* Subtitles out of active image area*/
+} otm_hdmi_wss_opensub_t;
+
+/**
+    This enumeration specifies values for Wide Screen Signalling surround sound
+    state, to be inserted into the analog TV signal.
+    See the #otm_hdmi_wss_data_t data structure.
+*/
+typedef enum {
+       WSS_SURROUND_NO = 1,    /* No surround sound information */
+       WSS_SURROUND_YES = 2,   /* Surround sound present */
+} otm_hdmi_wss_surround_t;
+
+/**
+    This enumeration contains the data type identifier for the WSS information
+    to pass to the TV encoder to be inserted into the analog TV signal.
+*/
+typedef enum {
+       WSS_NO_COPYRIGHT = 1,   /* No Copyright asserted or status unknown */
+       WSS_COPYRIGHT = 2,      /* Copyright Asserted */
+} otm_hdmi_wss_copyright_t;
+
+/**
+    This enumeration specifies values for Wide Screen Signalling copy
+    restriction state, to be inserted into the analog TV signal. See the
+
+*/
+typedef enum {
+       WSS_COPY_NO_REST = 1,   /* Copying not restricted */
+       WSS_COPY_RESTRICTED = 2 /* Copying Restricted */
+} otm_hdmi_wss_copy_t;
+
+/**
+
+    This data structure is used to pass closed captioning information to the
+    display driver.  The driver will pass this information to the TV encoder to
+    be inserted into the analog TV signal.
+*/
+typedef struct {
+       otm_hdmi_vbi_fieldid_t pd_vbi_field_id; /* Field ID identifier */
+       unsigned char data_length;
+                               /* Number of valid closed caption data bytes
+                               passed; must be an even number, with a
+                               maximum value of 8.
+                               */
+       unsigned char ccdata[8];
+                               /* Array containing the closed caption data
+                               to be inserted.
+                               */
+} otm_hdmi_cc_data_t;
+
+/**
+    This data structure is used to pass PAL Wide Screen signaling from an
+    application to the display driver.  The driver will pass this
+    information to the TV encoder to be inserted into the PAL analog TV signal.
+
+    Teletext is not supported in silicon. Teletext in subtitle always is 0.
+
+    Standard in use:
+    ETSI EN 300 294 V1.4.1 2003-2004
+*/
+typedef struct {
+       bool enabled; /* OTM_HDMI_TRUE => Enabled */
+       otm_hdmi_wss_aspect_t aspect; /* Aspect Ratio */
+       otm_hdmi_wss_camera_t cam_mode; /* Camera Mode */
+       otm_hdmi_wss_ce_t color_enc; /* Color Encoding */
+       otm_hdmi_wss_helpers_t helpers; /* Helpers Present */
+       otm_hdmi_wss_opensub_t open_sub; /* Open Subtitles */
+       otm_hdmi_wss_surround_t surround; /* Surround sound */
+       otm_hdmi_wss_copyright_t copyright; /* Copyright assertion */
+       otm_hdmi_wss_copy_t copy_rest;  /* Copy Restriction */
+} otm_hdmi_wss_data_t;
+
+/**
+    This data structure is used to pass Copy Generation Management System
+    (Analog) information from the application to the display driver.  The driver
+    will pass this information to the TV encoder to be inserted into the analog
+    TV signal.
+
+    XDS CEA-608 based CGMS-A should be passed using the Closed Captioning API.
+    See #otm_hdmi_cc_data_t
+
+    Standard is use: IEC 61880 480i Line20, EIA/CEA-805 480p Line 41,
+                       720p Line 24 , and 1080i Line 19
+*/
+typedef struct {
+       bool enabled; /* OTM_HDMI_TRUE => Enabled */
+       otm_hdmi_cgms_copy_t copyGen; /* CGMS-A data see #otm_hdmi_cgms_copy_t*/
+       otm_hdmi_cgms_aspect_t aspect; /* Wide Screen signaling. */
+       otm_hdmi_acp_mode_t mv; /* APS */
+       bool analog_src; /* Analog Source Bit */
+} otm_hdmi_cgms_data_t;
+
+/**
+    This enumeration is used to specify values for the #OTM_HDMI_ATTR_ID_SVIDEO
+    attribute
+*/
+typedef enum {
+       OTM_HDMI_TVOUT_TYPE_COMPOSITE, /* Composite only */
+       OTM_HDMI_TVOUT_TYPE_SVIDEO, /* S-Video only */
+       OTM_HDMI_TVOUT_TYPE_COMPONENT, /* Reserved for internal use */
+       OTM_HDMI_TVOUT_TYPE_CVBSSV, /* Composite and S-video */
+} otm_hdmi_tvout_type_t;
+
+/**
+
+*   This data structure is used to pass Copy Generation
+*   Management System (Analog) Type B information from the
+*   application to the display driver.  The driver will pass
+*   this information to the TV encoder to be inserted into the
+*   analog TV signal.
+
+    XDS CEA-608 based CGMS-A should be passed using the Closed Captioning API.
+    See #otm_hdmi_cc_data_t
+
+    Standard is use: EIA/CEA-805 480p Line 40,
+                       720p Line 23 , and 1080i Line 18, 581
+*/
+typedef struct {
+       bool enabled;   /* OTM_HDMI_TRUE => Enabled */
+       otm_hdmi_cgms_aspect_t aspect;  /* Wide Screen signaling IEC 61880. */
+       bool analog_src;        /* Analog Source Bit */
+       bool activeFormatValid;
+       bool barDataValid;
+       otm_hdmi_cgms_scan_t scanData;
+       otm_hdmi_cgms_colorimetery colorimetery;
+       unsigned char activeFormat;
+       bool RCI;
+       otm_hdmi_acp_mode_t mv; /* APS */
+       otm_hdmi_cgms_copy_t copyGen;   /* CGMS-A data
+                                       see #otm_hdmi_cgms_copy_t */
+       unsigned short lineEndTop;
+       unsigned short lineStartBottom;
+       unsigned short pixelEndLeft;
+       unsigned short pixelStartRight;
+} otm_hdmi_cgms_type_b_data_t;
+
+/* Defines the size of the Teletext data packet. */
+#define TELETEXT_NUM_LINES 32
+#define TELETEXT_LINE_LENGTH 46
+
+/**
+
+*   This data structure is used as part of otm_hdmi_teletext_data_t
+*   structure to more easily fill out the PES header.
+*
+*   The packet structure is for a single Teletext line. This is
+*   a convenience structure that describes the PES data header
+*   defined in section 4.3 ETSI EN 300-472.
+*
+*   Only data_unit_id's of Teletext Data (0x02) and Teletext
+*   subtitles (0x03) will be processed by the driver. Stuffing
+*   (0xFF) will be ignored. A value of 0x00 will generate a
+*   warning.
+*
+*   Line numbers with a field id of 0 will have 313 added.
+*   Line numbers outside the VBI will generate a warning.
+*/
+typedef struct {
+       unsigned char type:8;   /* Data unit ID */
+       unsigned char length:8; /* Length is required to be 44. */
+       unsigned char line:5;   /* VBI line */
+       unsigned char field:1;  /* VBI Field, 1 is bottom field */
+       unsigned char:2;        /* padding */
+       unsigned char framing_code:8;   /* Framing Code is required
+                                               to be 0xE4. */
+       unsigned char data[42]; /* Teletext data */
+} teletext_packet_t;
+
+/**
+
+*   This data structure is used to pass Teletext and Subtitle
+*   information to be reinserted into the VBI of the PAL signal
+*
+*   The packet structure contains up to two field's teletext
+*   lines with a 4-byte PES data header as defined in section
+*   4.3 ETSI EN 300-472.
+*
+*   Only data_unit_id's of Teletext Data (0x02) and Teletext
+*   subtitles (0x03) will be processed by the driver. Stuffing
+*   (0xFF) will be ignored. A value of 0x00 will generate a
+*   warning.
+*
+*   Line numbers with a field id of 0 will have 313 added.
+*   Line numbers outside the VBI will generate a warning.
+*/
+typedef struct {
+       bool enabled;   /* OTM_HDMI_TRUE => Enabled */
+       union {
+               teletext_packet_t packet[TELETEXT_NUM_LINES];
+               unsigned char
+                raw_data[TELETEXT_NUM_LINES][TELETEXT_LINE_LENGTH];
+       };
+} otm_hdmi_teletext_data_t;
+
+/* H D M I   S P E C I F I C   D A T A   T Y P E S */
+
+/**
+   This structure defines the HDMI audio data blocks.
+*/
+typedef struct {
+       unsigned int format;
+       unsigned int max_channels;
+       unsigned int fs;
+       unsigned int ss_bitrate;
+} otm_hdmi_audio_cap_t;
+
+/**
+    A CEC Source Physical Address.
+*/
+typedef struct {
+       unsigned char a;
+       unsigned char b;
+       unsigned char c;
+       unsigned char d;
+} otm_hdmi_src_phys_addr_t;
+
+/**
+    This data structure represents additional sink details not-available through
+    port attributes
+*/
+typedef struct {
+       unsigned short manufac_id; /* Sink manufacturer ID */
+       unsigned short product_code; /* Sink product code */
+       bool hdmi; /* Sink is HDMI */
+       bool ycbcr444; /* Sink supports YCbCr444 */
+       bool ycbcr422; /* Sink supports YCbCr422 */
+       otm_hdmi_src_phys_addr_t spa; /* CEC source physical address a.b.c.d*/
+       unsigned int speaker_map; /* Speaker allocation map */
+       bool dc_30; /* Sink supports 30-bit color */
+       bool dc_36; /* Sink supports 36-bit color */
+       bool dc_y444; /* Sink supports YCbCr444 in supported DC modes*/
+       bool xvycc601; /* Sink supports xvYCC BT601 Colorimetry */
+       bool xvycc709; /* Sink supports xvYCC BT709 Colorimetry */
+       bool supports_ai; /* Sink supports aux audio information */
+       unsigned int max_tmds_clock; /* Sink MAX TMDS clock in MHz. */
+       bool latency_present; /* Sink lipsync data valid */
+       bool latency_int_present; /* Sink Interlaced lipsync
+                                               data valid */
+       bool hdmi_video_present; /* Sink Supports HDMI spec.
+                                               video modes */
+       int latency_video; /* progressive modes video latency */
+       int latency_audio; /* progressive modes audio latency */
+       int latency_video_interlaced; /* interlaced modes video latency */
+       int latency_audio_interlaced; /* interlaced modes audio latency */
+       bool enabled_3d; /* Sink supports 3D video modes */
+       bool num_modes_3d; /* DEPRECATED; */
+       unsigned char max_horz_image_size; /* Sink's screen size in cm */
+       unsigned char max_vert_image_size; /* Sink's screen size in cm */
+       unsigned char name[14]; /* Sink's name */
+       bool rgb_quant_full; /* RGB quantization mode selectable */
+       bool ycc_quant_full; /* YCC quantization mode selectable */
+} otm_hdmi_sink_info_t;
+
+/**
+    This data structure represents 128 byte EDID block
+*/
+typedef struct {
+       unsigned char index; /* Block number to read */
+       unsigned char data[128]; /* Block contents */
+} otm_hdmi_edid_block_t;
+
+/**
+    This data structure represents HDCP topology information
+*/
+typedef struct {
+       bool hdcp_1p1;  /* Sink supports HDCP 1.1 */
+       bool repeater;  /* Sink is a repeater */
+       bool max_cascade_exceeded; /* Maximum allowed depth exceeded */
+       unsigned int depth; /* Topology depth */
+       bool max_devs_exceeded; /* Maximum allowed device
+                                               number exceeded */
+       unsigned int device_count; /* Number of devices connected
+                                               to the repeater */
+       unsigned char aksv[5]; /* AKSV */
+       unsigned char bksv[5]; /* BKSV read from connected sink */
+       unsigned long long an; /* An */
+       unsigned short ri; /* Ri */
+       unsigned short ri_prime; /* Ri' from Sink */
+       unsigned short pj; /* Pj */
+       unsigned short pj_prime; /* Pj' from Sink */
+} otm_hdmi_hdcp_info_t;
+
+/**
+    This enumeration defines the command IDs for the HDMI audio commands.
+    See #otm_hdmi_audio_ctrl_t.
+*/
+typedef enum {
+       OTM_HDMI_AUDIO_START, /* Start audio playback */
+       OTM_HDMI_AUDIO_STOP, /* Stop audio playback */
+       OTM_HDMI_AUDIO_SET_FORMAT, /* Set audio format */
+       OTM_HDMI_AUDIO_GET_CAPS, /* Retrieve descriptor of audio blocks */
+       OTM_HDMI_AUDIO_WRITE, /* For driver internal use only */
+       OTM_HDMI_AUDIO_SET_CHANNEL_STATUS, /* Set channel status info */
+       OTM_HDMI_AUDIO_GET_CHANNEL_STATUS, /* Get channel status info */
+} otm_hdmi_audio_cmd_id_t;
+
+/**
+    This enumeration defines IDs for different HDMI audio formats.
+*/
+/* IMPORTANT: DO NOT change order!!! */
+typedef enum {
+       OTM_HDMI_AUDIO_FORMAT_UNDEFINED = 0x00,
+       OTM_HDMI_AUDIO_FORMAT_PCM,
+       OTM_HDMI_AUDIO_FORMAT_AC3,
+       OTM_HDMI_AUDIO_FORMAT_MPEG1,
+       OTM_HDMI_AUDIO_FORMAT_MP3,
+       OTM_HDMI_AUDIO_FORMAT_MPEG2,
+       OTM_HDMI_AUDIO_FORMAT_AAC,
+       OTM_HDMI_AUDIO_FORMAT_DTS,
+       OTM_HDMI_AUDIO_FORMAT_ATRAC,
+       OTM_HDMI_AUDIO_FORMAT_OBA,
+       OTM_HDMI_AUDIO_FORMAT_DDP,
+       OTM_HDMI_AUDIO_FORMAT_DTSHD,
+       OTM_HDMI_AUDIO_FORMAT_MLP,
+       OTM_HDMI_AUDIO_FORMAT_DST,
+       OTM_HDMI_AUDIO_FORMAT_WMA_PRO,
+} otm_hdmi_audio_fmt_t;
+
+/**
+    This enumeration defines IDs for different HDMI audio sampling frequencies.
+*/
+typedef enum {
+       OTM_HDMI_AUDIO_FS_32_KHZ = 0x01,
+       OTM_HDMI_AUDIO_FS_44_1_KHZ = 0x02,
+       OTM_HDMI_AUDIO_FS_48_KHZ = 0x04,
+       OTM_HDMI_AUDIO_FS_88_2_KHZ = 0x08,
+       OTM_HDMI_AUDIO_FS_96_KHZ = 0x10,
+       OTM_HDMI_AUDIO_FS_176_4_KHZ = 0x20,
+       OTM_HDMI_AUDIO_FS_192_KHZ = 0x40,
+} otm_hdmi_audio_fs_t;
+
+/**
+    This enumeration defines IDs for different HDMI audio sample sizes.
+*/
+typedef enum {
+       OTM_HDMI_AUDIO_SS_UNDEFINED = 0x00,     /* Undefined value */
+       OTM_HDMI_AUDIO_SS_16 = 0x01,    /* 16 bits */
+       OTM_HDMI_AUDIO_SS_20 = 0x02,    /* 20 bits */
+       OTM_HDMI_AUDIO_SS_24 = 0x04,    /* 24 bits */
+} otm_hdmi_audio_ss_t;
+
+/**
+    Enumeration of the different audio speaker allocation options defined in the
+    CEA-861D specification.
+*/
+typedef enum {
+       OTM_HDMI_AUDIO_SPEAKER_MAP_FLFR = 0x0001,
+       OTM_HDMI_AUDIO_SPEAKER_MAP_LFE = 0x0002,
+       OTM_HDMI_AUDIO_SPEAKER_MAP_FC = 0x0004,
+       OTM_HDMI_AUDIO_SPEAKER_MAP_RLRR = 0x0008,
+       OTM_HDMI_AUDIO_SPEAKER_MAP_RC = 0x0010,
+       OTM_HDMI_AUDIO_SPEAKER_MAP_FLCFRC = 0x0020,
+       OTM_HDMI_AUDIO_SPEAKER_MAP_RLCRRC = 0x0040,
+       OTM_HDMI_AUDIO_SPEAKER_MAP_FLWFRW = 0x0080,
+       OTM_HDMI_AUDIO_SPEAKER_MAP_FLHFRH = 0x0100,
+       OTM_HDMI_AUDIO_SPEAKER_MAP_TC = 0x0200,
+       OTM_HDMI_AUDIO_SPEAKER_MAP_FCH = 0x0400,
+} otm_hdmi_audio_speaker_map_t;
+
+/**
+    This structure represents different audio commands
+*/
+typedef struct {
+       otm_hdmi_audio_cmd_id_t cmd_id; /* Audio command type */
+
+       union /* Audio command details */
+       {
+               struct  /* Arguments for #OTM_HDMI_AUDIO_SET_FORMAT command. */
+               {
+                       otm_hdmi_audio_fmt_t fmt; /* Audio format */
+                       otm_hdmi_audio_fs_t fs; /* Sampling frequency */
+                       unsigned int ch; /* Number of channels */
+                       otm_hdmi_audio_ss_t ss; /* Sample size [in bits] */
+                       otm_hdmi_audio_speaker_map_t map; /* Speaker allocation
+                                                               map */
+               } _set_config;
+
+               struct /* Arguments for #OTM_HDMI_AUDIO_GET_CAPS command. */
+               {
+                       unsigned int index; /* Capability number */
+                       otm_hdmi_audio_cap_t cap; /* Capability content */
+               } _get_caps;
+
+               struct /* Arguments for #OTM_HDMI_AUDIO_WRITE command */
+               {
+                       unsigned int samples; /* Audio samples buffer address*/
+                       unsigned int silence; /* Audio silence buffer address*/
+                       unsigned int size; /* Audio data buffer size */
+                       unsigned int id; /* Audio buffer ID */
+                       bool sync; /* Type of write operation */
+               } _write;
+
+               struct /* Arguments for #OTM_HDMI_AUDIO_STOP command */
+               {
+                       bool sync; /* Type of stop request */
+               } _stop;
+
+               struct /* Arguments for
+                       #OTM_HDMI_AUDIO_SET_CHANNEL_STATUS command */
+               {
+                       unsigned int lsw; /* Least significant word of
+                                               ch status */
+                       unsigned int msw; /* Most significant word of
+                                               ch status */
+               } _channel_status;
+
+       } data;
+
+} otm_hdmi_audio_ctrl_t;
+
+#define HDMI_DIP_PACKET_HEADER_LEN     3
+#define HDMI_DIP_PACKET_DATA_LEN       28
+
+/**
+    This structure represents generic HDMI packet
+*/
+typedef struct {
+       uint8_t header[HDMI_DIP_PACKET_HEADER_LEN];
+       union {
+               uint8_t data[HDMI_DIP_PACKET_DATA_LEN];
+               uint32_t data32[HDMI_DIP_PACKET_DATA_LEN/4];
+       };
+} otm_hdmi_packet_t;
+
+/**
+    This structure represents HDMI packet slot number
+*/
+typedef enum {
+       OTM_HDMI_PACKET_SLOT_0,
+       OTM_HDMI_PACKET_SLOT_1,
+       OTM_HDMI_PACKET_SLOT_AVI,
+} otm_hdmi_packet_slot_t;
+
+/**
+    This structure is used to submit data via #OTM_HDMI_SEND_HDMI_PACKET service
+    provided by #otm_hdmi_port_send
+*/
+typedef struct {
+       otm_hdmi_packet_t packet;
+       otm_hdmi_packet_slot_t slot;
+} otm_hdmi_packet_info_t;
+
+/**
+    This enumeration is used to specify values for the
+    #OTM_HDMI_ATTR_ID_USE_EDID attribute
+*/
+typedef enum {
+       OTM_HDMI_USE_EDID_NONE = 0,
+       OTM_HDMI_USE_EDID_REAL = 1,
+       OTM_HDMI_USE_EDID_SAFE = 2,
+} otm_hdmi_use_edid_t;
+
+/**
+*   This enumeration represents YC Delay amounts
+*/
+typedef enum {
+       OTM_HDMI_YC_DELAY_NONE, /* No YC delay */
+       OTM_HDMI_YC_DELAY_ADVANCE, /* Y 0.5 Pixel Advance delay */
+       OTM_HDMI_YC_DELAY_MINUS /* Y 1.0 Pixel delay */
+} otm_hdmi_yc_delay_t;
+
+/**
+*   This enumeration represents vswing equalization values
+*/
+typedef enum {
+       OTM_HDMI_EQUALIZE_NONE, /* Equalization disabled */
+       OTM_HDMI_EQUALIZE_10,   /* Equalization 10%, not supported on CE3100 */
+       OTM_HDMI_EQUALIZE_20,   /* Equalization 20% */
+       OTM_HDMI_EQUALIZE_30,   /* Equalization 30%, not supported on CE3100 */
+       OTM_HDMI_EQUALIZE_40,   /* Equalization 40% */
+       OTM_HDMI_EQUALIZE_50,   /* Equalization 50%, not supported on CE3100 */
+       OTM_HDMI_EQUALIZE_60,   /* Equalization 60% */
+       OTM_HDMI_EQUALIZE_70,   /* Equalization 70%, not supported on CE3100 */
+       OTM_HDMI_EQUALIZE_80,   /* Equalization 80% */
+} otm_hdmi_equalize_t;
+
+/**
+*   This enumeration represents transmit level amplitude values
+*/
+typedef enum {
+       OTM_HDMI_TRANSMIT_LEVEL_300, /* 300 mV, not supported on CE3100 */
+       OTM_HDMI_TRANSMIT_LEVEL_325, /* 325 mV, not supported on CE3100 */
+       OTM_HDMI_TRANSMIT_LEVEL_350, /* 350 mV, not supported on CE3100 */
+       OTM_HDMI_TRANSMIT_LEVEL_375, /* 375 mV, not supported on CE3100 */
+       OTM_HDMI_TRANSMIT_LEVEL_400, /* 400 mV, not supported on CE3100 */
+       OTM_HDMI_TRANSMIT_LEVEL_425, /* 425 mV, not supported on CE3100 */
+       OTM_HDMI_TRANSMIT_LEVEL_450, /* 450 mV */
+       OTM_HDMI_TRANSMIT_LEVEL_475, /* 475 mV, not supported on CE3100 */
+       OTM_HDMI_TRANSMIT_LEVEL_500, /* 500 mV */
+       OTM_HDMI_TRANSMIT_LEVEL_525, /* 525 mV, not supported on CE3100 */
+       OTM_HDMI_TRANSMIT_LEVEL_550, /* 550 mV */
+       OTM_HDMI_TRANSMIT_LEVEL_575, /* 575 mV, not supported on CE3100 */
+       OTM_HDMI_TRANSMIT_LEVEL_600, /* 600 mV */
+       OTM_HDMI_TRANSMIT_LEVEL_625, /* 625 mV, not supported on CE3100 */
+       OTM_HDMI_TRANSMIT_LEVEL_650, /* 650 mV, not supported on CE3100 */
+       OTM_HDMI_TRANSMIT_LEVEL_675, /* 675 mV, not supported on CE3100 */
+} otm_hdmi_transmit_level_t;
+
+/**
+*   This enumeration represents termination impedance values
+*/
+typedef enum {
+       OTM_HDMI_TERMINATION_OPEN, /* Open */
+       OTM_HDMI_TERMINATION_677, /* 677 Ohm, not supported on CE3100 */
+       OTM_HDMI_TERMINATION_398, /* 398 Ohm, not supported on CE3100 */
+       OTM_HDMI_TERMINATION_250, /* 250 Ohm, not supported on CE3100 */
+       OTM_HDMI_TERMINATION_200, /* 200 Ohm */
+       OTM_HDMI_TERMINATION_100, /* 100 Ohm */
+       OTM_HDMI_TERMINATION_88, /* 88 Ohm, not supported on CE3100 */
+       OTM_HDMI_TERMINATION_78, /* 78 Ohm, not supported on CE3100 */
+       OTM_HDMI_TERMINATION_72, /* 72 Ohm, not supported on CE3100 */
+       OTM_HDMI_TERMINATION_67, /* 67 Ohm */
+       OTM_HDMI_TERMINATION_65, /* 65 Ohm, not supported on CE3100 */
+       OTM_HDMI_TERMINATION_50, /* 50 Ohm */
+} otm_hdmi_termination_t;
+
+/**
+*   This enumeration represents current adjustment values
+*/
+typedef enum {
+       OTM_HDMI_CURRENT_0MA,   /* 0 mA */
+       OTM_HDMI_CURRENT_40MA,  /* 40 mA */
+       OTM_HDMI_CURRENT_60MA,  /* 60 mA */
+       OTM_HDMI_CURRENT_10MA,  /* 10 mA */
+       OTM_HDMI_CURRENT_250MA, /* 250 mA */
+       OTM_HDMI_CURRENT_290MA, /* 290 mA */
+       OTM_HDMI_CURRENT_310MA, /* 310 mA */
+       OTM_HDMI_CURRENT_350MA, /* 350 mA */
+} otm_hdmi_current_t;
+
+/**
+*   This enumeration represents band gap resistor values
+*/
+typedef enum {
+       OTM_HDMI_BGLVL_788, /* 0.788v not supported on CE4100 */
+       OTM_HDMI_BGLVL_818, /* 0.818v not supported on CE4100 */
+       OTM_HDMI_BGLVL_854, /* 0.854v not supported on CE4100
+                               [CE3100 default] */
+       OTM_HDMI_BGLVL_891, /* 0.891v not supported on CE4100 */
+       OTM_HDMI_BGLVL_820, /* 0.82v  not supported on CE3100
+                               [CE4100 default] */
+       OTM_HDMI_BGLVL_800, /* 0.80v  not supported on CE3100 */
+       OTM_HDMI_BGLVL_780, /* 0.78v  not supported on CE3100 */
+       OTM_HDMI_BGLVL_760, /* 0.76v  not supported on CE3100 */
+       OTM_HDMI_BGLVL_750, /* 0.75v  not supported on CE3100 */
+       OTM_HDMI_BGLVL_720, /* 0.72v  not supported on CE3100 */
+       OTM_HDMI_BGLVL_660, /* 0.66v  not supported on CE3100 */
+       OTM_HDMI_BGLVL_600, /* 0.60v  not supported on CE3100 */
+} otm_hdmi_bglvl_t;
+
+/**
+  This structure is used to submit data via #OTM_HDMI_SEND_HDMI_PACKET service
+  provided by #otm_hdmi_port_send and is intended for adjustments of PHY clock
+  and data lines.
+*/
+typedef struct {
+       otm_hdmi_equalize_t clock_equalization;
+                               /**< Clock equalization percentage.  On CE3100,
+                               *   same value is used for both clock and data.
+                               */
+       otm_hdmi_equalize_t data_equalization;
+                               /**< Data equalization percentage.
+                               *   IGNORED ON CE3100
+                               */
+       otm_hdmi_transmit_level_t clock_transmit_level;
+                               /**< Clock transmit level in mV.  On CE3100,
+                               *   same value is used for both clock and data.
+                               */
+       otm_hdmi_transmit_level_t data_transmit_level;
+                               /**< Data transmit level in mV.
+                               *   IGNORED ON CE3100.
+                               */
+       otm_hdmi_termination_t clock_termination;
+                               /**< Clock termination in ohms. On CE3100, same
+                               *   value is used for both clock and data.
+                               */
+       otm_hdmi_termination_t data_termination;
+                               /**< Data termination in ohms.
+                               *   IGNORED ON CE3100.
+                               */
+       otm_hdmi_current_t clock_current;
+                               /**< Clock current in mA.  On CE3100, same value
+                               *   is used for both clock and data.
+                               */
+       otm_hdmi_current_t data_current;
+                               /**< Data current in mA.  IGNORED ON CE3100 */
+       otm_hdmi_bglvl_t bandgap_level;
+                               /**< Same value used for both clock and data */
+} otm_hdmi_phy_info_t;
+
+/**
+*   This enumeration represents different HDCP states
+*/
+typedef enum {
+       OTM_HDMI_HDCP_STATUS_OFF, /* HDCP is disabled */
+       OTM_HDMI_HDCP_STATUS_IN_PROGRESS, /* HDCP is enabled but not
+                                               authenticated yet */
+       OTM_HDMI_HDCP_STATUS_ON, /* HDCP is enabled and is authenticated */
+} otm_hdmi_hdcp_status_t;
+
+/**
+*   This enumeration represents audio clock values with respect to which
+*   internal audio divisor value is chosen
+*/
+typedef enum {
+       OTM_HDMI_AUDIO_CLOCK_24,        /* Audio clock is running at 24MHz */
+       OTM_HDMI_AUDIO_CLOCK_36,        /* Audio clock is running at 36Mhz */
+       OTM_HDMI_AUDIO_CLOCK_16,        /* Audio clock is running at 16Mhz */
+} otm_hdmi_audio_clock_t;
+
+/**
+*   This enumeration is used to specify values for the #OTM_HDMI_ATTR_ID_MUTE
+*   attribute
+*/
+typedef enum {
+       OTM_HDMI_MUTE_OFF = 0x0,        /* Unmute */
+       OTM_HDMI_MUTE_VIDEO = 0x1,      /* Mute video only */
+       OTM_HDMI_MUTE_AUDIO = 0x2,      /* Mute audio only */
+       OTM_HDMI_MUTE_BOTH = 0x3,       /* Mute both audio and video */
+} otm_hdmi_mute_t;
+
+#endif /* _OTM_HDMI_DEFS_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/include/otm_hdmi_types.h b/drivers/staging/mrst/drv/otm_hdmi/pil/include/otm_hdmi_types.h
new file mode 100644 (file)
index 0000000..e1172b4
--- /dev/null
@@ -0,0 +1,463 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+       Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+       Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#ifndef _OTM_HDMI_TYPES_H
+#define _OTM_HDMI_TYPES_H
+
+/**
+ *     typedef enum otm_hdmi_ret_t - OTM HDMI module return code definition
+ *     OTM_HDMI_SUCCESS:       Function executed without errors.
+ *     OTM_HDMI_ERR_NO_MEMORY: Could not allocate memory.
+ *     OTM_HDMI_ERR_FAILED:    This is a generic error code  means that a
+ *                              system call or call to some other software
+ *                              external to the driver.
+ *     OTM_HDMI_ERR_INTERNAL:  A condition that "should not be possible" was
+ *                              detected within the driver. This generally
+ *                              means there is nothing the application can do
+ *                              to correct the problem.
+ */
+typedef enum {
+       OTM_HDMI_SUCCESS = 0,
+       /**<
+       Function executed without errors
+       */
+       OTM_HDMI_ERR_INVAL = 0x01,
+       /**<
+       An invalid argument was passed.
+       */
+       OTM_HDMI_ERR_BUSY = 0x02,
+       /**<
+       An operation could not be completed because a needed resource is in use.
+       */
+       OTM_HDMI_ERR_DISPLAY = 0x03,
+       /**<
+       An invalid display ID was passed.
+       */
+       OTM_HDMI_ERR_SURFACE = 0x04,
+       /**<
+       An invalid surface ID, or the ID of a surface that is not
+       appropriate for the requested operation, was passed.
+       */
+       OTM_HDMI_ERR_COMMAND = 0x05,
+       /**<
+       An internal command processing error occurred
+       */
+       OTM_HDMI_ERR_NULL_ARG = 0x06,
+       /**<
+       A required argument was missing.  Either a NULL pointer or a count
+       of 0 was passed for a required argument.
+       */
+       OTM_HDMI_ERR_NO_MEMORY = 0x07,
+       /**<
+       Could not allocate memory.
+       */
+       OTM_HDMI_ERR_FAILED = 0x08,
+       /**<
+       This is a generic error code that generally means that a system
+       call or call to some other software external to the driver
+       returned a failure code.
+       */
+       OTM_HDMI_ERR_INTERNAL = 0x09,
+       /**<
+       A condition that "should not be possible" was detected within the
+       driver.  This generally means there is nothing the application can
+       do to correct the problem.
+       */
+       OTM_HDMI_ERR_NOT_IMPL = 0x0a,
+       /**<
+       The function is not currently implemented for the target chip.
+       */
+       OTM_HDMI_ERR_MAPPED = 0x0b,
+       /**<
+       Operation not permitted on the mapped surface.
+       */
+       OTM_HDMI_ERR_NO_INIT = 0x0c,
+       /**<
+       A GDL function was called without a preceding call to gdl_init().
+       */
+       OTM_HDMI_ERR_NO_HW_SUPPORT = 0x0d,
+       /**<
+       The target chip does not support the requested function.  Examples:
+       - A graphics rendering option is not supported by the graphics core
+         in the target chip.
+       - A plane or port driver does not support a requested attribute.
+       - An attempt was made to request the attribute list from a port
+         driver that does not support any attributes.
+       */
+       OTM_HDMI_ERR_INVAL_PF = 0x0e,
+       /**<
+       An unknown pixel format, or a pixel format not supported by the
+       attempted operation, was passed.
+       */
+       OTM_HDMI_ERR_INVAL_RECT = 0x0f,
+       /**<
+       An invalid argument of type #gdl_rectangle_t was passed to the function.
+       */
+       OTM_HDMI_ERR_ATTR_ID = 0x10,
+       /**<
+       An undefined ID was specified for a plane attribute or a port
+       driver attribute.
+       */
+       OTM_HDMI_ERR_ATTR_NO_SUPPORT = 0x11,
+       /**<
+       An unsupported ID was specified for a plane attribute or a port
+       driver attribute.
+       */
+       OTM_HDMI_ERR_ATTR_READONLY = 0x12,
+       /**<
+       An attempt was made to set the value of a read-only plane attribute
+       or port driver attribute.
+       */
+       OTM_HDMI_ERR_ATTR_VALUE = 0x13,
+       /**<
+       An invalid value was specified for a plane attribute or a port
+       driver attribute.
+       */
+       OTM_HDMI_ERR_PLANE_CONFLICT = 0x14,
+       /**<
+       An attempt was made to change the display mode to a resolution too
+       small to accommodate all of the currently enabled planes at their
+       current positions on the display. Move/shrink the affected planes first.
+       */
+       OTM_HDMI_ERR_DISPLAY_CONFLICT = 0x15,
+       /**<
+       An attempt was made to change either display resolution or plane
+       size/origin, such that part/all of the plane will no longer be on the
+       display.
+       - If the display resolution is being reduced, change plane size/origin
+         first.
+       - If plane size is being increased, increase the display resolution
+         first, or reposition the plane.
+       - If plane origin is being changed, make sure you have picked an
+         appropriate origin given the current plane size and display
+         resolution.
+       */
+       OTM_HDMI_ERR_TIMEOUT = 0x16,
+       /**<
+       The requested timeout period occurred before the requested
+       operation trigger occurred.
+       */
+       OTM_HDMI_ERR_MISSING_BEGIN = 0x17,
+        /**<
+        An attempt was made to set a plane attribute without first calling
+        gdl_config_begin().
+        */
+       OTM_HDMI_ERR_PLANE_ID = 0x18,
+       /**<
+       An invalid plane ID was passed.  The ID is undefined, the plane is not
+       supported by the target chip, or the plane is not supported by the
+       called function.
+       */
+       OTM_HDMI_ERR_INVAL_PTR = 0x19,
+       /**<
+       On Linux, a copy between user and kernel space failed.  This
+       probably indicates an invalid user space (argument) pointer.
+       */
+
+       OTM_HDMI_ERR_INVAL_HEAP = 0x1a,
+       /**<
+       An invalid heap was passed for addition or removal. Attempt
+       to add overlaping heaps will cause this error too.
+       */
+
+       OTM_HDMI_ERR_HEAP_IN_USE = 0x1b,
+       /**<
+       Heap removal was attempted while at least one surface was allocated
+       from that heap.
+       */
+
+       OTM_HDMI_ERR_INVAL_CALLBACK = 0x1c,
+       /**<
+       Invalid callback (null) was passed to gdl_event_register() function
+       */
+
+       OTM_HDMI_ERR_SCALING_POLICY = 0x1d,
+       /**<
+       A single scaling policy is required and was not specified for the
+       unsupported for the specified display ID.
+       */
+
+       OTM_HDMI_ERR_INVAL_EVENT = 0x1e,
+       /**<
+       Invalid event was passed to functions expecting #gdl_app_event_t.
+       */
+
+       OTM_HDMI_ERR_INVAL_IOCTL = 0x1f,
+       /**<
+       Invalid IOCTL request was sent to kernel module
+       */
+       OTM_HDMI_ERR_SCHED_IN_ATOMIC = 0x20,
+       /**<
+       Scheduling was attempted while being in atomic context.
+       */
+       OTM_HDMI_ERR_MMAP = 0x21,
+       /**<
+       Memory mapping failed
+       */
+       OTM_HDMI_ERR_HDCP = 0x22,
+       /**<
+       HDCP failure
+       */
+       OTM_HDMI_ERR_CONFIG = 0x23,
+       /**<
+       Platform config file error: either a required entry in the
+       platform configuration file is missing, or its entry is invalid.
+       */
+       OTM_HDMI_ERR_HDMI_AUDIO_PLAYBACK = 0x24,
+       /**<
+       HDMI Audio start / stop / set buffer / set format command was
+       initiated at the wrong time.
+       */
+       OTM_HDMI_ERR_HDMI_AUDIO_BUFFER_FULL = 0x25,
+       /**<
+       Given data does not fit in the internal buffer
+       */
+       OTM_HDMI_ERR_PLANE_ORIGIN_ODD = 0x26,
+       /**<
+       In interlaced display modes, active planes must be configured with
+       their origins on even display lines. This error is returned when:
+       - in a progressive display mode: an attempt is made to change to an
+         interlaced display mode while there is an active plane does not
+         meet this requirement.
+       - in an interlaced display mode:
+          - an attempt is made to reconfigure an active plane's origin
+            to an odd line number, OR
+          - an attempt is made to activate (by flipping a surface to) a
+            plane that doesn't meet this requirement.
+       */
+       OTM_HDMI_ERR_PLANE_HEIGHT_ODD = 0x27,
+       /**<
+       In interlaced display modes, active planes must be configured with
+       their even heights. This error is returned when:
+       - in a progressive display mode: an attempt is made to change to an
+         interlaced display mode while there is an active plane does not
+         meet this requirement.
+       - in an interlaced display mode:
+          - an attempt is made to reconfigure an active plane's height
+            to an odd value, OR
+          - an attempt is made to activate (by flipping a surface to) a
+            plane that doesn't meet this requirement.
+       */
+       OTM_HDMI_ERR_HANDLE = 0x28,
+       /**<
+       Handle is not valid.
+       */
+       OTM_HDMI_ERR_TVMODE_UNDEFINED = 0x29,
+       /**<
+       Display has undefined tv mode set on it.
+       */
+       OTM_HDMI_ERR_PREMULT_CONFLICT = 0x2a,
+       /**<
+       An attempt was made to enable the #OTM_HDMI_PLANE_ALPHA_PREMULT
+       attribute and one of the following incompatible features at the same
+       time:
+       - Chroma keying on the same plane
+         (#OTM_HDMI_PLANE_CHROMA_KEY_SRC_ENABLE set to #OTM_HDMI_TRUE).
+       - Gamma removal on the same plane (#OTM_HDMI_PLANE_REVERSE_GAMMA_TYPE
+         set to a value other than #OTM_HDMI_GAMMA_LINEAR.
+       - color space conversion (the value of the plane's
+
+         space of the display to which it is connected).
+       - a non-RGB pixel format.
+       */
+
+       OTM_HDMI_ERR_SUSPENDED = 0x2b,
+       /**<
+       An attempt was made to execute a command while the driver was in a
+       suspended mode. During the suspended mode driver is in a low-power
+       state and no access to hardware is allowed.
+       */
+
+       OTM_HDMI_ERR_STEREO_PLANE = 0x2c,
+       /**<
+       An attempt was made to stereo-flip to a plane unlinked to a right view
+       while a two-plane stereo display mode is in effect.
+       */
+
+       OTM_HDMI_ERR_CE4100_3D_ORIGIN = 0x2d,
+       /**<
+       On the CE4100, the origin of a plane's destination rectangle cannot
+       exceed 922 when OTM_HDMI_STEREO_FRAME_PACKING_2 stereo frame format is
+       in use.
+       */
+
+       OTM_HDMI_ERR_HDCP_KSV_INVALID = 0x2e,
+       /**<
+       HDCP invalid KSV
+       */
+       OTM_HDMI_ERR_HDCP_KSV_REVOKED = 0x2f,
+       /**<
+       HDCP revoked KSV
+       */
+       OTM_HDMI_ERR_HDCP_NO_ACK = 0x30,
+       /**<
+       HDCP I2C timeout when receiving R'
+       */
+       OTM_HDMI_ERR_HDCP_LINK_INTEGRITY = 0x31,
+       /**<
+       HDCP R != R'
+       */
+
+       OTM_HDMI_ERR_PERM = 0x32,
+       /**<
+       Callers permissions are insufficient to perform a requested action.
+       */
+
+       /**********************************************************************
+        ATTENTION!!: WHEN ADDING AN ERROR CODE MAKE SURE TO:
+        - Search for a value marked "Currently unused" in the list above
+          before adding a new value at the end.
+        - Include inline (doxygen) documentation for the new error.
+        - Add the new error to _error_string() in debug.c
+       **********************************************************************/
+} otm_hdmi_ret_t;
+
+/* ----------------------------------------------------------------------
+ *                 D I S P L A Y   M O D E
+ * ----------------------------------------------------------------------
+ */
+
+/**
+ *  Refresh rates for TV mode definitions.
+ *
+ *  Refresh rate is the number of times the display is updated per second.
+ *  This is the number of frames per second for progressive display modes;
+ *  the number of fields (half the number of frames) per second for interlaced
+ *  display modes.
+ *
+*/
+typedef enum {
+       OTM_HDMI_REFRESH_23_98, /* 23.98... (24/1.001)    */
+       OTM_HDMI_REFRESH_24,    /* 24                     */
+       OTM_HDMI_REFRESH_25,    /* 25                     */
+       OTM_HDMI_REFRESH_29_97, /* 29.97... (30/1.001)    */
+       OTM_HDMI_REFRESH_30,    /* 30 - DEPRECATED: This value is normally only
+                                  used on computer systems and should be used
+                                  with care, if at all. The corresponding TV
+                                  rate is 30/(1.001) (see
+                                  #OTM_HDMI_REFRESH_29_97). */
+       OTM_HDMI_REFRESH_50,    /* 50                     */
+       OTM_HDMI_REFRESH_59_94, /* 59.94... (60/1.001)    */
+       OTM_HDMI_REFRESH_60,    /* 60 - DEPRECATED: This value is normally only
+                                  used on computer systems and should be used
+                                  with care, if at all. The corresponding TV
+                                  rate is 60/(1.001) (see
+                                  #OTM_HDMI_REFRESH_59_94). */
+       OTM_HDMI_REFRESH_48,    /* 48 - DEPRECATED: This value is normally only
+                                  used on HDMI output with special sink device
+                                  and should be used with care, if at all. */
+       OTM_HDMI_REFRESH_47_96, /* 47.96... (48/1.001)   */
+       OTM_HDMI_REFRESH_NONE,  /* Indicates that mode is not set */
+       OTM_HDMI_REFRESH_USER_DEFINED
+                               /* External (non-Intel) port drivers may define
+                                  additional refresh rates that the support.
+                                  Their IDs must be numbered starting at this
+                                  value. */
+} otm_hdmi_refresh_t;
+
+/**
+ *  This enumeration is used to specify a stereo (3D) video format.  The SOCs
+ *  on which each format is supported are specified within square brackets.
+ *
+ *  Format names ending in "_2" indicate that the format requires the use of
+ *  two UPPs, one for the left view and one for the right. The
+ *
+ *  to reference the left view plane in order to link them together.
+ *
+ *  OTM_HDMI_STEREO_NONE
+ *     Indicates a mono display mode (no stereo format is in use).
+ *
+ *  OTM_HDMI_STEREO_FRAME_PACKING_2
+ *     Frame packing format implemented with 2 planes per stream.
+ *
+ *  OTM_HDMI_STEREO_FRAME_PACKING [CE4200-B and above]
+ *     Single-plane frame packing format.
+ *
+ *  OTM_HDMI_STEREO_SIDE_BY_SIDE_HALF_2
+ *     Side-by-side format with the horizontal axis subsampled by half,
+ *     implemented with 2 planes per stream.
+ *     NOTE: Planes should be configured and buffers for graphics
+ *     allocated at half horizontal resolution. The TV set is responsible for
+ *     scaling the blended image horizontally by 2.
+ *
+ *  OTM_HDMI_STEREO_TOP_BOTTOM_HALF_2
+ *     Top-and-bottom format with the vertical axis subsampled by half,
+ *     implemented with 2 planes per stream.
+ *     NOTE: Planes should be configured and buffers for graphics
+ *     allocated at half vertical resolution. The TV set is responsible for
+ *     scaling the blended image vertically by 2.
+ *
+ *  OTM_HDMI_STEREO_FRAME_SEQUENTIAL
+ *     Frame sequential format, a format used internally in some Digital TV
+ *     sets for direct output to the panel. NOTE: in order to use Frame
+ *     Sequential format, the HDMI port driver must be loaded with the dtv=1
+ *     command line argument.
+*/
+typedef enum {
+       OTM_HDMI_STEREO_NONE = 0xabcdef01,
+       OTM_HDMI_STEREO_FRAME_PACKING_2,
+       OTM_HDMI_STEREO_FRAME_PACKING,
+       OTM_HDMI_STEREO_SIDE_BY_SIDE_HALF_2,
+       OTM_HDMI_STEREO_TOP_BOTTOM_HALF_2,
+       OTM_HDMI_STEREO_FRAME_SEQUENTIAL,
+} otm_hdmi_stereo_t;
+#endif /* _OTM_HDMI_TYPES_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/specific/include/ps_hdmi.h b/drivers/staging/mrst/drv/otm_hdmi/pil/specific/include/ps_hdmi.h
new file mode 100644 (file)
index 0000000..1a5a8c8
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#ifndef _PLATFORM_SPEC_H
+#define _PLATFORM_SPEC_H
+
+#include <linux/pci.h>
+#include "otm_hdmi_types.h"
+#include "otm_hdmi_defs.h"
+#include "edid.h"
+
+otm_hdmi_ret_t ps_hdmi_i2c_edid_read(void *ctx, unsigned int sp,
+                                 unsigned int offset, void *buffer,
+                                 unsigned int size);
+
+otm_hdmi_ret_t ps_hdmi_pci_dev_init(void *context, struct pci_dev *pdev);
+
+otm_hdmi_ret_t ps_hdmi_pci_dev_deinit(void *context);
+
+/*
+ * Description: fetches the preferred scaling type for a aprticular platfrom.
+ *
+ * @context:           hdmi context pointer
+ * @pscaling_type:     pointer to be updated with scaling type info.
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t ps_hdmi_get_pref_scalingtype(void *context,
+                                               int *pscaling_type);
+#endif /* _PLATFORM_SPEC_H */
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/specific/mfld/ps_hdmi.c b/drivers/staging/mrst/drv/otm_hdmi/pil/specific/mfld/ps_hdmi.c
new file mode 100644 (file)
index 0000000..f994033
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include "otm_hdmi_types.h"
+
+#include <asm/io.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include "otm_hdmi.h"
+#include "ipil_hdmi.h"
+
+#define PS_HDMI_MMIO_RESOURCE 0
+#define PS_VDC_OFFSET 0x00000000
+#define PS_VDC_SIZE 0x000080000
+#define PS_MSIC_PCI_DEVICE_ID 0x0831
+#define PS_MSIC_VRINT_ADDR 0xFFFF7FCB
+#define PS_MSIC_VRINT_IOADDR_LEN 0x02
+
+otm_hdmi_ret_t ps_hdmi_pci_dev_init(void *context, struct pci_dev *pdev)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       int result = 0;
+       struct pci_dev *msic_pdev = NULL;
+       unsigned int vdc_start;
+       uint32_t pci_address = 0;
+       uint8_t pci_dev_revision = 0;
+       hdmi_context_t *ctx = NULL;
+
+       if (pdev == NULL || context == NULL) {
+               rc = OTM_HDMI_ERR_INTERNAL;
+               goto exit;
+       }
+       ctx = (hdmi_context_t *)context;
+
+       pr_debug("\nget resource start\n");
+       result = pci_read_config_dword(pdev, 16, &vdc_start);
+       if (result != 0) {
+               rc = OTM_HDMI_ERR_FAILED;
+               goto exit;
+       }
+       pci_address = vdc_start + PS_VDC_OFFSET;
+
+       pr_debug("\nmap IO region\n");
+       /* Map IO region and save its length */
+       ctx->io_length = PS_VDC_SIZE;
+       ctx->io_address = ioremap_cache(pci_address, ctx->io_length);
+       if (!ctx->io_address) {
+               rc = OTM_HDMI_ERR_FAILED;
+               goto exit;
+       }
+
+       /* Map IO region for IRQ registers */
+       ctx->dev.irq_io_address = ioremap_nocache(PS_MSIC_VRINT_ADDR,
+                                               PS_MSIC_VRINT_IOADDR_LEN);
+       if (!ctx->dev.irq_io_address) {
+               rc = OTM_HDMI_ERR_FAILED;
+               goto exit;
+       }
+
+       pr_debug("\nget PCI dev revision\n");
+       result = pci_read_config_byte(pdev, 8, &pci_dev_revision);
+       if (result != 0) {
+               rc = OTM_HDMI_ERR_FAILED;
+               goto exit;
+       }
+       ctx->dev.id = pci_dev_revision;
+
+       pr_debug("pci_get_device for 0x%x\n", PS_MSIC_PCI_DEVICE_ID);
+       msic_pdev = pci_get_device(PCI_VENDOR_INTEL,
+                                       PS_MSIC_PCI_DEVICE_ID, msic_pdev);
+       if (msic_pdev == NULL) {
+               rc = OTM_HDMI_ERR_FAILED;
+               goto exit;
+       }
+       pr_debug("pci_enable_device for 0x%x\n",
+                                       PS_MSIC_PCI_DEVICE_ID);
+       result = pci_enable_device(msic_pdev);
+       if (result) {
+               rc = OTM_HDMI_ERR_FAILED;
+               goto exit;
+       }
+       pr_debug("IRQ number assigned = %d\n", msic_pdev->irq);
+       ctx->irq_number = msic_pdev->irq;
+
+exit:
+       return rc;
+}
+
+otm_hdmi_ret_t ps_hdmi_pci_dev_deinit(void *context)
+{
+       otm_hdmi_ret_t rc = OTM_HDMI_SUCCESS;
+       struct pci_dev *msic_pdev = NULL;
+       hdmi_context_t *ctx = NULL;
+
+       if (context == NULL) {
+               rc = OTM_HDMI_ERR_INTERNAL;
+               goto exit;
+       }
+       ctx = (hdmi_context_t *)context;
+
+       /* unmap IO region */
+       iounmap(ctx->io_address) ;
+
+       /* TODO: Enable this on DV1 once PCI issue is resolved */
+       msic_pdev = pci_get_device(PCI_VENDOR_INTEL,
+                                       PS_MSIC_PCI_DEVICE_ID, msic_pdev);
+       if (msic_pdev == NULL) {
+               rc = OTM_HDMI_ERR_FAILED;
+               goto exit;
+       }
+       pci_disable_device(msic_pdev);
+exit:
+       return rc;
+}
+
+otm_hdmi_ret_t ps_hdmi_i2c_edid_read(void *ctx, unsigned int sp,
+                                 unsigned int offset, void *buffer,
+                                 unsigned int size)
+{
+       hdmi_context_t *context = (hdmi_context_t *)ctx;
+
+       char *src = context->edid_raw + sp * SEGMENT_SIZE + offset;
+       memcpy(buffer, src, size);
+
+       return OTM_HDMI_SUCCESS;
+}
diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/specific/mfld/ps_hdmi_tablet.c b/drivers/staging/mrst/drv/otm_hdmi/pil/specific/mfld/ps_hdmi_tablet.c
new file mode 100644 (file)
index 0000000..36e47be
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+  The full GNU General Public License is included in this distribution
+  in the file called LICENSE.GPL.
+
+  Contact Information:
+
+  Intel Corporation
+  2200 Mission College Blvd.
+  Santa Clara, CA  95054
+
+  BSD LICENSE
+
+  Copyright(c) 2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include "otm_hdmi_types.h"
+#include "hdmi_internal.h"
+
+#define PS_PREF_SCALINGTYPE IPIL_TIMING_SCALE_FULLSCREEN
+
+/*
+ * Description: fetches the preferred scaling type for a aprticular platfrom.
+ *
+ * @context:           hdmi context pointer
+ * @pscaling_type:     pointer to be updated with scaling type info.
+ *
+ * Returns:    OTM_HDMI_SUCCESS on success
+ *             OTM_HDMI_ERR_INVAL on NULL input arguments
+ */
+otm_hdmi_ret_t ps_hdmi_get_pref_scalingtype(void *context,
+                                               int *pscaling_type)
+{
+       hdmi_context_t *ctx = (hdmi_context_t *)context;
+
+       if (NULL == ctx || NULL == pscaling_type)
+               return OTM_HDMI_ERR_INVAL;
+
+       *pscaling_type = PS_PREF_SCALINGTYPE;
+
+       return OTM_HDMI_SUCCESS;
+}
+