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>
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
--- /dev/null
+########################################################################
+#
+# 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
--- /dev/null
+/*
+
+ 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();
+}
+
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+
+ 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);
+}
--- /dev/null
+/*
+
+ 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 */
+
--- /dev/null
+/*
+
+ 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__*/
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+
+ 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;
+}
+
--- /dev/null
+/*
+
+ 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;
+ }
+}
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+
+ 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
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+
+ 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?
+ */
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+
+ 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");
+}
--- /dev/null
+/*
+
+ 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;
+}
+
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+ 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_ */
--- /dev/null
+/*
+
+ 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);
+}
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+ 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 */
+};
--- /dev/null
+/*
+
+ 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
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+
+ 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 */
--- /dev/null
+/*
+
+ 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;
+}
--- /dev/null
+/*
+
+ 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;
+}
+