/*
* hdmi.c
*
* HDMI interface DSS driver setting for TI's OMAP4 family of processor.
* Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
* Authors: Yong Zhi
* Mythri pk <mythripk@ti.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#define DSS_SUBSYS_NAME "HDMI"
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/clk.h>
#include <video/omapdss.h>
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
#include <sound/soc.h>
#include <sound/pcm_params.h>
#include "ti_hdmi_4xxx_ip.h"
#endif
#include "ti_hdmi.h"
#include "dss.h"
#include "dss_features.h"
#define HDMI_WP 0x0
#define HDMI_CORE_SYS 0x400
#define HDMI_CORE_AV 0x900
#define HDMI_PLLCTRL 0x200
#define HDMI_PHY 0x300
/* HDMI EDID Length move this */
#define HDMI_EDID_MAX_LENGTH 256
#define EDID_TIMING_DESCRIPTOR_SIZE 0x12
#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36
#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80
#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4
#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4
#define OMAP_HDMI_TIMINGS_NB 34
#define HDMI_DEFAULT_REGN 16
#define HDMI_DEFAULT_REGM2 1
static struct {
struct mutex lock;
struct omap_display_platform_data *pdata;
struct platform_device *pdev;
struct hdmi_ip_data ip_data;
int code;
int mode;
struct clk *sys_clk;
} hdmi;
/*
* Logic for the below structure :
* user enters the CEA or VESA timings by specifying the HDMI/DVI code.
* There is a correspondence between CEA/VESA timing and code, please
* refer to section 6.3 in HDMI 1.3 specification for timing code.
*
* In the below structure, cea_vesa_timings corresponds to all OMAP4
* supported CEA and VESA timing values.code_cea corresponds to the CEA
* code, It is used to get the timing from cea_vesa_timing array.Similarly
* with code_vesa. Code_index is used for back mapping, that is once EDID
* is read from the TV, EDID is parsed to find the timing values and then
* map it to corresponding CEA or VESA index.
*/
static const struct hdmi_timings cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = {
{ {640, 480, 25200, 96, 16, 48, 2, 10, 33} , 0 , 0},
{ {1280, 720, 74250, 40, 440, 220, 5, 5, 20}, 1, 1},
{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1},
{ {720, 480, 27027, 62, 16, 60, 6, 9, 30}, 0, 0},
{ {2880, 576, 108000, 256, 48, 272, 5, 5, 39}, 0, 0},
{ {1440, 240, 27027, 124, 38, 114, 3, 4, 15}, 0, 0},
{ {1440, 288, 27000, 126, 24, 138, 3, 2, 19}, 0, 0},
{ {1920, 540, 74250, 44, 528, 148, 5, 2, 15}, 1, 1},
{ {1920, 540, 74250, 44, 88, 148, 5, 2, 15}, 1, 1},
{ {1920, 1080, 148500, 44, 88, 148, 5, 4, 36}, 1, 1},
{ {720, 576, 27000, 64, 12, 68, 5, 5, 39}, 0, 0},
{ {1440, 576, 54000, 128, 24, 136, 5, 5, 39}, 0, 0},
{ {1920, 1080, 148500, 44, 528, 148, 5, 4, 36}, 1, 1},
{ {2880, 480, 108108, 248, 64, 240, 6, 9, 30}, 0, 0},
{ {1920, 1080, 74250, 44, 638, 148, 5, 4, 36}, 1, 1},
/* VESA From Here */
{ {640, 480, 25175, 96, 16, 48, 2 , 11, 31}, 0, 0},
{ {800, 600, 40000, 128, 40, 88, 4 , 1, 23}, 1, 1},
{ {848, 480, 33750, 112, 16, 112, 8 , 6, 23}, 1, 1},
{ {1280, 768, 79500, 128, 64, 192, 7 , 3, 20}, 1, 0},
{ {1280, 800, 83500, 128, 72, 200, 6 , 3, 22}, 1, 0},
{ {1360, 768, 85500,<