public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] OMAP4 : DSS2 : HDMI support
@ 2011-02-25 14:21 Mythri P K
  2011-02-25 14:21 ` [PATCH 1/8] OMAP4 : DSS2 : Add display type HDMI to DSS2 Mythri P K
                   ` (7 more replies)
  0 siblings, 8 replies; 23+ messages in thread
From: Mythri P K @ 2011-02-25 14:21 UTC (permalink / raw)
  To: linux-omap; +Cc: tomi.valkeinen, Mythri P K

Adding HDMI support to OMAP4.

HDMI is a driver that is similar to the VENC or the DSI driver to support
HDMI/DVI sink device.

The current design adheres to the DSS2 architecture.

It is split into the HDMI DSS driver and HDMI panel driver.

HDMI DSS driver (hdmi.c) is responsible for
1.OMAP related configuration such as
	1.Listening to the DSS_HDMI irq which signals changes such as hot-plug
		detect,physical attach/detach.
	2.calculate the PLL values based on the TV resolution that is selected
	3.configuration of the Mux/GPIO settings.
2.HDMI configuration such asbased on the parameters read from the EDID of the
sink device :
	1. Configuration of the PHY registers.
	2. Configuration of the PLL registers and setting of the TMDS clock.
	3. Configuration of the DDC to read the EDID data when available.
	4. Configuration of the core registers to set:
		a. set the video registers to the timing and format that
			is selected.
		b. set the audio registers based on the EDID value read and
			user selected parameters.
		c. Set the AVI info frame registers to configure the auxilary
			info frame which are repeated.
HDMI Panel Driver (hdmi_omap4_panel.c) . This is a panel driver which acts
as the controlling device which synchronizes the audio and video portion of the
driver.[enable ,disable , notification to audio on suspend etc].
It registers hdmi driver to the omap_dss bus and calls the functionality
of the HDMI DSS driver.
It is also provides the interface for users 
	1.To read the EDID contents and also confiure the timings based on EDID.
	2.To configure AVI Inforframe based on the the EDID(sink capability).

Note : Mux handling with hwmod is dependent on pm_runtime_sync ,so mux with hwmod
will be posted once patch series with pm_runtime_sync is done.

verified on 4430 SDP ES2.1 - Penguins on HDMI and DVI TV.
verified on PANDA ES2.1 - Penguins on HDMI and DVI TV.

Mythri P K (8):
  OMAP4 : DSS2 : Add display type HDMI to DSS2
  OMAP4 : DSS2 : Add display structure in the board file for OMAP4 sdp
  OMAP4 : DSS : HDMI: HDMI specific display controller and dss change.
  OMAP4 : DSS : HDMI: HDMI driver header file addition
  OMAP4 : DSS2 : HDMI: HDMI driver addition in the DSS drivers
    interface
  OMAP4 : DSS2 : HDMI: HDMI panel driver addition in the DSS
  OMAP4 : DSS : HDMI: Call to HDMI module init to register driver.
  OMAP4 : DSS2 : Add display structure in the board file for OMAP4
    pandaboard

 arch/arm/mach-omap2/board-4430sdp.c        |   82 ++
 arch/arm/mach-omap2/board-omap4panda.c     |   82 ++
 arch/arm/plat-omap/include/plat/display.h  |    1 +
 drivers/video/omap2/dss/Kconfig            |   16 +
 drivers/video/omap2/dss/Makefile           |    2 +
 drivers/video/omap2/dss/core.c             |    8 +
 drivers/video/omap2/dss/dispc.c            |    5 +
 drivers/video/omap2/dss/display.c          |    8 +
 drivers/video/omap2/dss/dss.c              |    7 +
 drivers/video/omap2/dss/dss.h              |   35 +
 drivers/video/omap2/dss/dss_features.c     |    2 +-
 drivers/video/omap2/dss/hdmi.c             | 1276 ++++++++++++++++++++++++++++
 drivers/video/omap2/dss/hdmi.h             |  700 +++++++++++++++
 drivers/video/omap2/dss/hdmi_omap4_panel.c |  190 +++++
 drivers/video/omap2/dss/manager.c          |    9 +-
 drivers/video/omap2/dss/overlay.c          |    6 +-
 16 files changed, 2424 insertions(+), 5 deletions(-)
 create mode 100644 drivers/video/omap2/dss/hdmi.c
 create mode 100644 drivers/video/omap2/dss/hdmi.h
 create mode 100644 drivers/video/omap2/dss/hdmi_omap4_panel.c


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 1/8] OMAP4 : DSS2 : Add display type HDMI to DSS2
  2011-02-25 14:21 [PATCH 0/8] OMAP4 : DSS2 : HDMI support Mythri P K
@ 2011-02-25 14:21 ` Mythri P K
  2011-02-25 14:21 ` [PATCH 2/8] OMAP4 : DSS2 : Add display structure in the board file for OMAP4 sdp Mythri P K
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 23+ messages in thread
From: Mythri P K @ 2011-02-25 14:21 UTC (permalink / raw)
  To: linux-omap; +Cc: tomi.valkeinen, Mythri P K

Adding HDMI type in dss_features , overlay and
the manager so that HDMI type of display will be recognized.

Signed-off-by: Mythri P K <mythripk@ti.com>
---
 arch/arm/plat-omap/include/plat/display.h |    1 +
 drivers/video/omap2/dss/display.c         |    5 +++++
 drivers/video/omap2/dss/dss_features.c    |    2 +-
 drivers/video/omap2/dss/manager.c         |    9 +++++++--
 drivers/video/omap2/dss/overlay.c         |    6 ++++--
 5 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h
index 4e936bd..e0bab29 100644
--- a/arch/arm/plat-omap/include/plat/display.h
+++ b/arch/arm/plat-omap/include/plat/display.h
@@ -60,6 +60,7 @@ enum omap_display_type {
 	OMAP_DISPLAY_TYPE_SDI		= 1 << 2,
 	OMAP_DISPLAY_TYPE_DSI		= 1 << 3,
 	OMAP_DISPLAY_TYPE_VENC		= 1 << 4,
+	OMAP_DISPLAY_TYPE_HDMI		= 1 << 5,
 };
 
 enum omap_plane {
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 22dd7a4..e10b303 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -345,6 +345,7 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
 			return 16;
 	case OMAP_DISPLAY_TYPE_VENC:
 	case OMAP_DISPLAY_TYPE_SDI:
+	case OMAP_DISPLAY_TYPE_HDMI:
 		return 24;
 	default:
 		BUG();
@@ -371,6 +372,7 @@ bool dss_use_replication(struct omap_dss_device *dssdev,
 	case OMAP_DISPLAY_TYPE_DPI:
 		bpp = dssdev->phy.dpi.data_lines;
 		break;
+	case OMAP_DISPLAY_TYPE_HDMI:
 	case OMAP_DISPLAY_TYPE_VENC:
 	case OMAP_DISPLAY_TYPE_SDI:
 		bpp = 24;
@@ -409,6 +411,9 @@ void dss_init_device(struct platform_device *pdev,
 #ifdef CONFIG_OMAP2_DSS_VENC
 	case OMAP_DISPLAY_TYPE_VENC:
 #endif
+#ifdef CONFIG_OMAP2_DSS_HDMI
+	case OMAP_DISPLAY_TYPE_HDMI:
+#endif
 		break;
 	default:
 		DSSERR("Support for display '%s' not compiled in.\n",
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 569eb42..701a2ce 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -102,7 +102,7 @@ static const enum omap_display_type omap4_dss_supported_displays[] = {
 	OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI,
 
 	/* OMAP_DSS_CHANNEL_DIGIT */
-	OMAP_DISPLAY_TYPE_VENC,
+	OMAP_DISPLAY_TYPE_VENC | OMAP_DISPLAY_TYPE_HDMI,
 
 	/* OMAP_DSS_CHANNEL_LCD2 */
 	OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 690217b..490c2b8 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -516,6 +516,8 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
 
 	if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) {
 		irq = DISPC_IRQ_EVSYNC_ODD;
+	} else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI) {
+		irq = DISPC_IRQ_EVSYNC_EVEN;
 	} else {
 		if (mgr->id == OMAP_DSS_CHANNEL_LCD)
 			irq = DISPC_IRQ_VSYNC;
@@ -537,7 +539,8 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
 	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
-	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
+	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
+			|| dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
 		irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
 	} else {
 		if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
@@ -614,7 +617,8 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
 	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
-	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
+	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
+			|| dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
 		irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
 	} else {
 		if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
@@ -1381,6 +1385,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
 		case OMAP_DISPLAY_TYPE_DBI:
 		case OMAP_DISPLAY_TYPE_SDI:
 		case OMAP_DISPLAY_TYPE_VENC:
+		case OMAP_DISPLAY_TYPE_HDMI:
 			default_get_overlay_fifo_thresholds(ovl->id, size,
 					&oc->burst_size, &oc->fifo_low,
 					&oc->fifo_high);
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index d558fb6..ea48936 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -737,7 +737,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
 			lcd2_mgr->set_device(lcd2_mgr, dssdev);
 			mgr = lcd2_mgr;
 		}
-	} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) {
+	} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
+			&& dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
 		if (!lcd_mgr->device || force) {
 			if (lcd_mgr->device)
 				lcd_mgr->unset_device(lcd_mgr);
@@ -746,7 +747,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
 		}
 	}
 
-	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) {
+	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
+			|| dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
 		if (!tv_mgr->device || force) {
 			if (tv_mgr->device)
 				tv_mgr->unset_device(tv_mgr);
-- 
1.5.6.3


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2/8] OMAP4 : DSS2 : Add display structure in the board file for OMAP4 sdp
  2011-02-25 14:21 [PATCH 0/8] OMAP4 : DSS2 : HDMI support Mythri P K
  2011-02-25 14:21 ` [PATCH 1/8] OMAP4 : DSS2 : Add display type HDMI to DSS2 Mythri P K
@ 2011-02-25 14:21 ` Mythri P K
  2011-02-27  9:13   ` Tomi Valkeinen
  2011-02-25 14:21 ` [PATCH 3/8] OMAP4 : DSS : HDMI: HDMI specific display controller and dss change Mythri P K
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 23+ messages in thread
From: Mythri P K @ 2011-02-25 14:21 UTC (permalink / raw)
  To: linux-omap; +Cc: tomi.valkeinen, Mythri P K

Adding  board file changes for display which adds the display structure
with HDMI as the default driver when the display init is called.
HDMI GPIO configurations are also done in this file.

Signed-off-by: Mythri P K <mythripk@ti.com>
---
 arch/arm/mach-omap2/board-4430sdp.c |   82 +++++++++++++++++++++++++++++++++++
 1 files changed, 82 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 07d1b20..334b6fd 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -35,6 +35,7 @@
 #include <plat/common.h>
 #include <plat/usb.h>
 #include <plat/mmc.h>
+#include <plat/display.h>
 
 #include "mux.h"
 #include "hsmmc.h"
@@ -47,6 +48,8 @@
 #define OMAP4SDP_MDM_PWR_EN_GPIO	157
 #define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO	184
 #define OMAP4_SFH7741_ENABLE_GPIO		188
+#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
+#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
 
 static struct gpio_led sdp4430_gpio_leds[] = {
 	{
@@ -552,6 +555,84 @@ static void __init omap_sfh7741prox_init(void)
 	}
 }
 
+static void sdp4430_hdmi_mux_init(void)
+{
+	/* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
+	omap_mux_init_signal("hdmi_hpd",
+			OMAP_PIN_INPUT_PULLUP);
+	omap_mux_init_signal("hdmi_cec",
+			OMAP_PIN_INPUT_PULLUP);
+	/* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
+	omap_mux_init_signal("hdmi_ddc_scl",
+			OMAP_PIN_INPUT_PULLUP);
+	omap_mux_init_signal("hdmi_ddc_sda",
+			OMAP_PIN_INPUT_PULLUP);
+}
+
+static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
+{
+	int status;
+
+	status = gpio_request_one(HDMI_GPIO_HPD, GPIOF_DIR_OUT,
+							"hdmi_gpio_hpd");
+	if (status) {
+		pr_err("Cannot request GPIO %d\n", HDMI_GPIO_HPD);
+		return status;
+	}
+	status = gpio_request_one(HDMI_GPIO_LS_OE, GPIOF_DIR_OUT,
+							"hdmi_gpio_ls_oe");
+	if (status) {
+		pr_err("Cannot request GPIO %d\n", HDMI_GPIO_LS_OE);
+		goto error1;
+	}
+
+	/* The value set a pulse */
+	gpio_set_value(HDMI_GPIO_HPD, 1);
+	gpio_set_value(HDMI_GPIO_LS_OE, 1);
+	gpio_set_value(HDMI_GPIO_HPD, 0);
+	gpio_set_value(HDMI_GPIO_LS_OE, 0);
+	gpio_set_value(HDMI_GPIO_HPD, 1);
+	gpio_set_value(HDMI_GPIO_LS_OE, 1);
+
+	return 0;
+
+error1:
+	gpio_free(HDMI_GPIO_HPD);
+
+	return status;
+}
+
+static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
+{
+	gpio_free(HDMI_GPIO_LS_OE);
+	gpio_free(HDMI_GPIO_HPD);
+}
+
+static struct omap_dss_device sdp4430_hdmi_device = {
+	.name = "hdmi",
+	.driver_name = "hdmi_panel",
+	.type = OMAP_DISPLAY_TYPE_HDMI,
+	.platform_enable = sdp4430_panel_enable_hdmi,
+	.platform_disable = sdp4430_panel_disable_hdmi,
+	.channel = OMAP_DSS_CHANNEL_DIGIT,
+};
+
+static struct omap_dss_device *sdp4430_dss_devices[] = {
+	&sdp4430_hdmi_device,
+};
+
+static struct omap_dss_board_info sdp4430_dss_data = {
+	.num_devices	= ARRAY_SIZE(sdp4430_dss_devices),
+	.devices	= sdp4430_dss_devices,
+	.default_device	= &sdp4430_hdmi_device,
+};
+
+void omap_4430sdp_display_init(void)
+{
+	sdp4430_hdmi_mux_init();
+	omap_display_init(&sdp4430_dss_data);
+}
+
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux board_mux[] __initdata = {
 	OMAP4_MUX(USBB2_ULPITLL_CLK, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
@@ -594,6 +675,7 @@ static void __init omap_4430sdp_init(void)
 		spi_register_board_info(sdp4430_spi_board_info,
 				ARRAY_SIZE(sdp4430_spi_board_info));
 	}
+	omap_4430sdp_display_init();
 }
 
 static void __init omap_4430sdp_map_io(void)
-- 
1.5.6.3


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 3/8] OMAP4 : DSS : HDMI: HDMI specific display controller and dss change.
  2011-02-25 14:21 [PATCH 0/8] OMAP4 : DSS2 : HDMI support Mythri P K
  2011-02-25 14:21 ` [PATCH 1/8] OMAP4 : DSS2 : Add display type HDMI to DSS2 Mythri P K
  2011-02-25 14:21 ` [PATCH 2/8] OMAP4 : DSS2 : Add display structure in the board file for OMAP4 sdp Mythri P K
@ 2011-02-25 14:21 ` Mythri P K
  2011-02-27  9:23   ` Tomi Valkeinen
  2011-02-25 14:21 ` [PATCH 4/8] OMAP4 : DSS : HDMI: HDMI driver header file addition Mythri P K
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 23+ messages in thread
From: Mythri P K @ 2011-02-25 14:21 UTC (permalink / raw)
  To: linux-omap; +Cc: tomi.valkeinen, Mythri P K

Adding changes to set gamma table bit for TV interface and function to select
between VENC and HDMI.

Signed-off-by: Mythri P K <mythripk@ti.com>
---
 drivers/video/omap2/dss/dispc.c |    5 +++++
 drivers/video/omap2/dss/dss.c   |    7 +++++++
 drivers/video/omap2/dss/dss.h   |    2 ++
 3 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 6d9bb17..16f1106 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1213,6 +1213,11 @@ void dispc_enable_zorder(enum omap_plane plane, bool enable)
 	dispc_write_reg(dispc_reg_att[plane], val);
 }
 
+void dispc_enable_gamma_table(bool enable)
+{
+	REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
+}
+
 static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
 {
 	u32 val;
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 99de4e1..127d42e 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -559,6 +559,13 @@ void dss_set_dac_pwrdn_bgz(bool enable)
 	REG_FLD_MOD(DSS_CONTROL, enable, 5, 5);	/* DAC Power-Down Control */
 }
 
+void dss_select_hdmi_venc(bool hdmi)
+{
+	REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15);	/* 0x1 for HDMI, 0x0 VENC */
+	if (hdmi)
+		REG_FLD_MOD(DSS_CONTROL, 0, 9, 8);
+}
+
 static int dss_init(bool skip_init)
 {
 	int r;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index b6f27fe..d199ba7 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -209,6 +209,7 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
 int dss_init_platform_driver(void);
 void dss_uninit_platform_driver(void);
 
+void dss_select_hdmi_venc(bool hdmi);
 void dss_save_context(void);
 void dss_restore_context(void);
 void dss_clk_enable(enum dss_clock clks);
@@ -352,6 +353,7 @@ void dispc_set_plane_pos(enum omap_plane plane, u16 x, u16 y);
 void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height);
 void dispc_set_channel_out(enum omap_plane plane,
 		enum omap_channel channel_out);
+void dispc_enable_gamma_table(bool enable);
 
 int dispc_setup_plane(enum omap_plane plane,
 		      u32 paddr, u16 screen_width,
-- 
1.5.6.3


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 4/8] OMAP4 : DSS : HDMI: HDMI driver header file addition
  2011-02-25 14:21 [PATCH 0/8] OMAP4 : DSS2 : HDMI support Mythri P K
                   ` (2 preceding siblings ...)
  2011-02-25 14:21 ` [PATCH 3/8] OMAP4 : DSS : HDMI: HDMI specific display controller and dss change Mythri P K
@ 2011-02-25 14:21 ` Mythri P K
  2011-02-27  9:28   ` Tomi Valkeinen
  2011-02-25 14:21 ` [PATCH 5/8] OMAP4 : DSS2 : HDMI: HDMI driver addition in the DSS drivers interface Mythri P K
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 23+ messages in thread
From: Mythri P K @ 2011-02-25 14:21 UTC (permalink / raw)
  To: linux-omap; +Cc: tomi.valkeinen, Mythri P K

Adding the hdmi interface driver header file (hdmi.h) to the dss driver.
Register and timing declaration to be used by the corresponding c file is added in this file.

Signed-off-by: Mythri P K <mythripk@ti.com>
---
 drivers/video/omap2/dss/hdmi.h |  691 ++++++++++++++++++++++++++++++++++++++++
 1 files changed, 691 insertions(+), 0 deletions(-)
 create mode 100644 drivers/video/omap2/dss/hdmi.h

diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h
new file mode 100644
index 0000000..7441835
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi.h
@@ -0,0 +1,691 @@
+/*
+ * hdmi.h
+ *
+ * HDMI driver definition for TI OMAP4 processors.
+ *
+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.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/>.
+ */
+
+#ifndef _HDMI_H_
+#define _HDMI_H_
+
+#include <linux/string.h>
+#include <plat/display.h>
+
+#define HDMI_WP			0x0
+#define HDMI_CORE_SYS		0x400
+#define HDMI_CORE_AV		0x900
+#define HDMI_PLLCTRL		0x200
+#define HDMI_PHY		0x300
+
+struct hdmi_reg { u16 idx; };
+
+#define HDMI_REG(idx)			((const struct hdmi_reg) { idx })
+
+/* HDMI Wrapper */
+#define HDMI_WP_REG(idx)			HDMI_REG(HDMI_WP + idx)
+
+#define HDMI_WP_REVISION			HDMI_WP_REG(0x0)
+#define HDMI_WP_SYSCONFIG			HDMI_WP_REG(0x10)
+#define HDMI_WP_IRQSTATUS_RAW			HDMI_WP_REG(0x24)
+#define HDMI_WP_IRQSTATUS			HDMI_WP_REG(0x28)
+#define HDMI_WP_PWR_CTRL			HDMI_WP_REG(0x40)
+#define HDMI_WP_IRQENABLE_SET			HDMI_WP_REG(0x2C)
+#define HDMI_WP_VIDEO_CFG			HDMI_WP_REG(0x50)
+#define HDMI_WP_VIDEO_SIZE			HDMI_WP_REG(0x60)
+#define HDMI_WP_VIDEO_TIMING_H			HDMI_WP_REG(0x68)
+#define HDMI_WP_VIDEO_TIMING_V			HDMI_WP_REG(0x6C)
+#define HDMI_WP_WP_CLK				HDMI_WP_REG(0x70)
+
+/* HDMI IP Core System */
+#define HDMI_CORE_SYS_REG(idx)			HDMI_REG(HDMI_CORE_SYS + idx)
+
+#define HDMI_CORE_SYS_VND_IDL			HDMI_CORE_SYS_REG(0x0)
+#define HDMI_CORE_SYS_DEV_IDL			HDMI_CORE_SYS_REG(0x8)
+#define HDMI_CORE_SYS_DEV_IDH			HDMI_CORE_SYS_REG(0xC)
+#define HDMI_CORE_SYS_DEV_REV			HDMI_CORE_SYS_REG(0x10)
+#define HDMI_CORE_SYS_SRST			HDMI_CORE_SYS_REG(0x14)
+#define HDMI_CORE_CTRL1				HDMI_CORE_SYS_REG(0x20)
+#define HDMI_CORE_SYS_SYS_STAT			HDMI_CORE_SYS_REG(0x24)
+#define HDMI_CORE_SYS_VID_ACEN			HDMI_CORE_SYS_REG(0x124)
+#define HDMI_CORE_SYS_VID_MODE			HDMI_CORE_SYS_REG(0x128)
+#define HDMI_CORE_SYS_INTR_STATE		HDMI_CORE_SYS_REG(0x1C0)
+#define HDMI_CORE_SYS_INTR1			HDMI_CORE_SYS_REG(0x1C4)
+#define HDMI_CORE_SYS_INTR2			HDMI_CORE_SYS_REG(0x1C8)
+#define HDMI_CORE_SYS_INTR3			HDMI_CORE_SYS_REG(0x1CC)
+#define HDMI_CORE_SYS_INTR4			HDMI_CORE_SYS_REG(0x1D0)
+#define HDMI_CORE_SYS_UMASK1			HDMI_CORE_SYS_REG(0x1D4)
+#define HDMI_CORE_SYS_TMDS_CTRL			HDMI_CORE_SYS_REG(0x208)
+#define HDMI_CORE_SYS_DE_DLY			HDMI_CORE_SYS_REG(0xC8)
+#define HDMI_CORE_SYS_DE_CTRL			HDMI_CORE_SYS_REG(0xCC)
+#define HDMI_CORE_SYS_DE_TOP			HDMI_CORE_SYS_REG(0xD0)
+#define HDMI_CORE_SYS_DE_CNTL			HDMI_CORE_SYS_REG(0xD8)
+#define HDMI_CORE_SYS_DE_CNTH			HDMI_CORE_SYS_REG(0xDC)
+#define HDMI_CORE_SYS_DE_LINL			HDMI_CORE_SYS_REG(0xE0)
+#define HDMI_CORE_SYS_DE_LINH_1			HDMI_CORE_SYS_REG(0xE4)
+#define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC		0x1
+#define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC		0x1
+#define HDMI_CORE_CTRL1_BSEL_24BITBUS		0x1
+#define HDMI_CORE_CTRL1_EDGE_RISINGEDGE		0x1
+
+/* HDMI DDC E-DID */
+#define HDMI_CORE_DDC_CMD			HDMI_CORE_SYS_REG(0x3CC)
+#define HDMI_CORE_DDC_STATUS			HDMI_CORE_SYS_REG(0x3C8)
+#define HDMI_CORE_DDC_ADDR			HDMI_CORE_SYS_REG(0x3B4)
+#define HDMI_CORE_DDC_OFFSET			HDMI_CORE_SYS_REG(0x3BC)
+#define HDMI_CORE_DDC_COUNT1			HDMI_CORE_SYS_REG(0x3C0)
+#define HDMI_CORE_DDC_COUNT2			HDMI_CORE_SYS_REG(0x3C4)
+#define HDMI_CORE_DDC_DATA			HDMI_CORE_SYS_REG(0x3D0)
+#define HDMI_CORE_DDC_SEGM			HDMI_CORE_SYS_REG(0x3B8)
+
+/* HDMI IP Core Audio Video */
+#define HDMI_CORE_AV_REG(idx)			HDMI_REG(HDMI_CORE_AV + idx)
+
+#define HDMI_CORE_AV_HDMI_CTRL			HDMI_CORE_AV_REG(0xBC)
+#define HDMI_CORE_AV_DPD			HDMI_CORE_AV_REG(0xF4)
+#define HDMI_CORE_AV_PB_CTRL1			HDMI_CORE_AV_REG(0xF8)
+#define HDMI_CORE_AV_PB_CTRL2			HDMI_CORE_AV_REG(0xFC)
+#define HDMI_CORE_AV_AVI_TYPE			HDMI_CORE_AV_REG(0x100)
+#define HDMI_CORE_AV_AVI_VERS			HDMI_CORE_AV_REG(0x104)
+#define HDMI_CORE_AV_AVI_LEN			HDMI_CORE_AV_REG(0x108)
+#define HDMI_CORE_AV_AVI_CHSUM			HDMI_CORE_AV_REG(0x10C)
+#define HDMI_CORE_AV_AVI_DBYTE(n)		HDMI_CORE_AV_REG(n * 4 + 0x110)
+#define HDMI_CORE_AV_AVI_DBYTE_NELEMS		HDMI_CORE_AV_REG(15)
+#define HDMI_CORE_AV_SPD_DBYTE			HDMI_CORE_AV_REG(0x190)
+#define HDMI_CORE_AV_SPD_DBYTE_NELEMS		HDMI_CORE_AV_REG(27)
+#define HDMI_CORE_AV_MPEG_DBYTE			HDMI_CORE_AV_REG(0x290)
+#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS		HDMI_CORE_AV_REG(27)
+#define HDMI_CORE_AV_GEN_DBYTE			HDMI_CORE_AV_REG(0x300)
+#define HDMI_CORE_AV_GEN_DBYTE_NELEMS		HDMI_CORE_AV_REG(31)
+#define HDMI_CORE_AV_GEN2_DBYTE			HDMI_CORE_AV_REG(0x380)
+#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS		HDMI_CORE_AV_REG(31)
+#define HDMI_CORE_AV_ACR_CTRL			HDMI_CORE_AV_REG(0x4)
+#define HDMI_CORE_AV_FREQ_SVAL			HDMI_CORE_AV_REG(0x8)
+#define HDMI_CORE_AV_N_SVAL1			HDMI_CORE_AV_REG(0xC)
+#define HDMI_CORE_AV_N_SVAL2			HDMI_CORE_AV_REG(0x10)
+#define HDMI_CORE_AV_N_SVAL3			HDMI_CORE_AV_REG(0x14)
+#define HDMI_CORE_AV_CTS_SVAL1			HDMI_CORE_AV_REG(0x18)
+#define HDMI_CORE_AV_CTS_SVAL2			HDMI_CORE_AV_REG(0x1C)
+#define HDMI_CORE_AV_CTS_SVAL3			HDMI_CORE_AV_REG(0x20)
+#define HDMI_CORE_AV_CTS_HVAL1			HDMI_CORE_AV_REG(0x24)
+#define HDMI_CORE_AV_CTS_HVAL2			HDMI_CORE_AV_REG(0x28)
+#define HDMI_CORE_AV_CTS_HVAL3			HDMI_CORE_AV_REG(0x2C)
+#define HDMI_CORE_AV_AUD_MODE			HDMI_CORE_AV_REG(0x50)
+#define HDMI_CORE_AV_SPDIF_CTRL			HDMI_CORE_AV_REG(0x54)
+#define HDMI_CORE_AV_HW_SPDIF_FS		HDMI_CORE_AV_REG(0x60)
+#define HDMI_CORE_AV_SWAP_I2S			HDMI_CORE_AV_REG(0x64)
+#define HDMI_CORE_AV_SPDIF_ERTH			HDMI_CORE_AV_REG(0x6C)
+#define HDMI_CORE_AV_I2S_IN_MAP			HDMI_CORE_AV_REG(0x70)
+#define HDMI_CORE_AV_I2S_IN_CTRL		HDMI_CORE_AV_REG(0x74)
+#define HDMI_CORE_AV_I2S_CHST0			HDMI_CORE_AV_REG(0x78)
+#define HDMI_CORE_AV_I2S_CHST1			HDMI_CORE_AV_REG(0x7C)
+#define HDMI_CORE_AV_I2S_CHST2			HDMI_CORE_AV_REG(0x80)
+#define HDMI_CORE_AV_I2S_CHST4			HDMI_CORE_AV_REG(0x84)
+#define HDMI_CORE_AV_I2S_CHST5			HDMI_CORE_AV_REG(0x88)
+#define HDMI_CORE_AV_ASRC			HDMI_CORE_AV_REG(0x8C)
+#define HDMI_CORE_AV_I2S_IN_LEN			HDMI_CORE_AV_REG(0x90)
+#define HDMI_CORE_AV_HDMI_CTRL			HDMI_CORE_AV_REG(0xBC)
+#define HDMI_CORE_AV_AUDO_TXSTAT		HDMI_CORE_AV_REG(0xC0)
+#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1		HDMI_CORE_AV_REG(0xCC)
+#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2		HDMI_CORE_AV_REG(0xD0)
+#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3		HDMI_CORE_AV_REG(0xD4)
+#define HDMI_CORE_AV_TEST_TXCTRL		HDMI_CORE_AV_REG(0xF0)
+#define HDMI_CORE_AV_DPD			HDMI_CORE_AV_REG(0xF4)
+#define HDMI_CORE_AV_PB_CTRL1			HDMI_CORE_AV_REG(0xF8)
+#define HDMI_CORE_AV_PB_CTRL2			HDMI_CORE_AV_REG(0xFC)
+#define HDMI_CORE_AV_AVI_TYPE			HDMI_CORE_AV_REG(0x100)
+#define HDMI_CORE_AV_AVI_VERS			HDMI_CORE_AV_REG(0x104)
+#define HDMI_CORE_AV_AVI_LEN			HDMI_CORE_AV_REG(0x108)
+#define HDMI_CORE_AV_AVI_CHSUM			HDMI_CORE_AV_REG(0x10C)
+#define HDMI_CORE_AV_SPD_TYPE			HDMI_CORE_AV_REG(0x180)
+#define HDMI_CORE_AV_SPD_VERS			HDMI_CORE_AV_REG(0x184)
+#define HDMI_CORE_AV_SPD_LEN			HDMI_CORE_AV_REG(0x188)
+#define HDMI_CORE_AV_SPD_CHSUM			HDMI_CORE_AV_REG(0x18C)
+#define HDMI_CORE_AV_MPEG_TYPE			HDMI_CORE_AV_REG(0x280)
+#define HDMI_CORE_AV_MPEG_VERS			HDMI_CORE_AV_REG(0x284)
+#define HDMI_CORE_AV_MPEG_LEN			HDMI_CORE_AV_REG(0x288)
+#define HDMI_CORE_AV_MPEG_CHSUM			HDMI_CORE_AV_REG(0x28C)
+#define HDMI_CORE_AV_CP_BYTE1			HDMI_CORE_AV_REG(0x37C)
+#define HDMI_CORE_AV_CEC_ADDR_ID		HDMI_CORE_AV_REG(0x3FC)
+#define HDMI_CORE_AV_SPD_DBYTE_ELSIZE		0x4
+#define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE		0x4
+#define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE		0x4
+#define HDMI_CORE_AV_GEN_DBYTE_ELSIZE		0x4
+
+/* PLL */
+#define HDMI_PLL_REG(idx)			HDMI_REG(HDMI_PLLCTRL + idx)
+
+#define PLLCTRL_PLL_CONTROL			HDMI_PLL_REG(0x0)
+#define PLLCTRL_PLL_STATUS			HDMI_PLL_REG(0x4)
+#define PLLCTRL_PLL_GO				HDMI_PLL_REG(0x8)
+#define PLLCTRL_CFG1				HDMI_PLL_REG(0xC)
+#define PLLCTRL_CFG2				HDMI_PLL_REG(0x10)
+#define PLLCTRL_CFG3				HDMI_PLL_REG(0x14)
+#define PLLCTRL_CFG4				HDMI_PLL_REG(0x20)
+
+/* HDMI PHY */
+#define HDMI_PHY_REG(idx)			HDMI_REG(HDMI_PHY + idx)
+
+#define HDMI_TXPHY_TX_CTRL			HDMI_PHY_REG(0x0)
+#define HDMI_TXPHY_DIGITAL_CTRL			HDMI_PHY_REG(0x4)
+#define HDMI_TXPHY_POWER_CTRL			HDMI_PHY_REG(0x8)
+#define HDMI_TXPHY_PAD_CFG_CTRL			HDMI_PHY_REG(0xC)
+
+/* HDMI EDID Length  */
+#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 REG_FLD_MOD(idx, val, start, end) \
+	hdmi_write_reg(idx, FLD_MOD(hdmi_read_reg(idx), val, start, end))
+
+u8		edid[HDMI_EDID_MAX_LENGTH] = {0};
+u8		edid_set;
+u8		header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0};
+struct		omap_video_timings edid_timings;
+
+/* HDMI timing structure */
+struct hdmi_timings {
+	struct omap_video_timings timings;
+	int vsync_pol;
+	int hsync_pol;
+};
+
+/*
+ * Logic for the below structure
+ * user enters the CEA or VESA timings by specifying
+ * the hdmicode which corresponds to CEA/VESA timings
+ * please refer to section 6.3 in HDMI 1.3 specification for timing code.
+ * There is a correspondence between CEA/VESA timing and code.
+ * In the below structure, cea_vesa_timings corresponds to all
+ * The OMAP4 supported timing  CEA and VESA timing values.
+ * code_cea corresponds to the CEA code entered by the user,
+ * The use of it is to get the timing from the cea_vesa_timing array.
+ * Similarly for code_vesa.
+ * code_index is backmapping, Once EDID is read from the TV
+ * EDID is parsed to find the timing values to map it back to the
+ * corresponding CEA or VESA index this structure is used.
+ */
+
+/*
+ * This is the structure which has all supported timing
+ * values that OMAP4 supports
+ */
+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, 112, 64, 256, 6 , 3, 18}, 1, 1},
+	{ {1280, 960, 108000, 112, 96, 312, 3 , 1, 36}, 1, 1},
+	{ {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38}, 1, 1},
+	{ {1024, 768, 65000, 136, 24, 160, 6, 3, 29}, 0, 0},
+	{ {1400, 1050, 121750, 144, 88, 232, 4, 3, 32}, 1, 0},
+	{ {1440, 900, 106500, 152, 80, 232, 6, 3, 25}, 1, 0},
+	{ {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30}, 1, 0},
+	{ {1366, 768, 85500, 143, 70, 213, 3, 3, 24}, 1, 1},
+	{ {1920, 1080, 148500, 44, 148, 80, 5, 4, 36}, 1, 1},
+	{ {1280, 768, 68250, 32, 48, 80, 7, 3, 12}, 0, 1},
+	{ {1400, 1050, 101000, 32, 48, 80, 4, 3, 23}, 0, 1},
+	{ {1680, 1050, 119000, 32, 48, 80, 6, 3, 21}, 0, 1},
+	{ {1280, 800, 79500, 32, 48, 80, 6, 3, 14}, 0, 1},
+	{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}
+};
+
+/*
+ * This is a static mapping array which maps the timing values
+ * with corresponding CEA / VESA code
+ */
+static int code_index[OMAP_HDMI_TIMINGS_NB] = {
+	1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32,
+	/* <--15 CEA 17--> vesa*/
+	4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A,
+	0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B
+};
+
+/*
+ * This is reverse static mapping which maps the CEA / VESA code
+ * to the corresponding timing values
+ */
+static int code_cea[39] = {
+	-1,  0,  3,  3,  2,  8,  5,  5, -1, -1,
+	-1, -1, -1, -1, -1, -1,  9, 10, 10,  1,
+	7,   6,  6, -1, -1, -1, -1, -1, -1, 11,
+	11, 12, 14, -1, -1, 13, 13,  4,  4
+};
+
+int code_vesa[85] = {
+	-1, -1, -1, -1, 15, -1, -1, -1, -1, 16,
+	-1, -1, -1, -1, 17, -1, 23, -1, -1, -1,
+	-1, -1, 29, 18, -1, -1, -1, 32, 19, -1,
+	-1, -1, 21, -1, -1, 22, -1, -1, -1, 20,
+	-1, 30, 24, -1, -1, -1, -1, 25, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, 31, 26, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+	-1, 27, 28, -1, 33};
+
+enum hdmi_phypwr {
+	HDMI_PHYPWRCMD_OFF = 0,
+	HDMI_PHYPWRCMD_LDOON = 1,
+	HDMI_PHYPWRCMD_TXON = 2
+};
+
+enum hdmi_pll_pwr {
+	HDMI_PLLPWRCMD_ALLOFF = 0,
+	HDMI_PLLPWRCMD_PLLONLY = 1,
+	HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
+	HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
+};
+
+enum hdmi_core_inputbus_width {
+	HDMI_INPUT_8BIT = 0,
+	HDMI_INPUT_10BIT = 1,
+	HDMI_INPUT_12BIT = 2
+};
+
+enum hdmi_core_dither_trunc {
+	HDMI_OUTPUTTRUNCATION_8BIT = 0,
+	HDMI_OUTPUTTRUNCATION_10BIT = 1,
+	HDMI_OUTPUTTRUNCATION_12BIT = 2,
+	HDMI_OUTPUTDITHER_8BIT = 3,
+	HDMI_OUTPUTDITHER_10BIT = 4,
+	HDMI_OUTPUTDITHER_12BIT = 5
+};
+
+enum hdmi_core_deepcolor_ed {
+	HDMI_DEEPCOLORPACKECTDISABLE = 0,
+	HDMI_DEEPCOLORPACKECTENABLE = 1
+};
+
+enum hdmi_core_packet_mode {
+	HDMI_PACKETMODERESERVEDVALUE = 0,
+	HDMI_PACKETMODE24BITPERPIXEL = 4,
+	HDMI_PACKETMODE30BITPERPIXEL = 5,
+	HDMI_PACKETMODE36BITPERPIXEL = 6,
+	HDMI_PACKETMODE48BITPERPIXEL = 7
+};
+
+enum hdmi_core_hdmi_dvi {
+	HDMI_DVI = 0,
+	HDMI_HDMI = 1
+};
+
+enum hdmi_core_tclkselclkmult {
+	FPLL05IDCK = 0,
+	FPLL10IDCK = 1,
+	FPLL20IDCK = 2,
+	FPLL40IDCK = 3
+};
+
+enum hdmi_core_fs {
+	FS_32000 = 0,
+	FS_44100 = 1
+};
+
+enum hdmi_core_layout {
+	LAYOUT_2CH = 0,
+	LAYOUT_8CH = 1
+};
+
+enum hdmi_core_cts_mode {
+	CTS_MODE_HW = 0,
+	CTS_MODE_SW = 1
+};
+
+enum hdmi_core_packet_ctrl {
+	PACKETENABLE = 1,
+	PACKETDISABLE = 0,
+	PACKETREPEATON = 1,
+	PACKETREPEATOFF = 0
+};
+
+/* INFOFRAME_AVI_ definitions */
+enum hdmi_core_infoframe {
+	INFOFRAME_AVI_DB1Y_RGB = 0,
+	INFOFRAME_AVI_DB1Y_YUV422 = 1,
+	INFOFRAME_AVI_DB1Y_YUV444 = 2,
+	INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0,
+	INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON =  1,
+	INFOFRAME_AVI_DB1B_NO = 0,
+	INFOFRAME_AVI_DB1B_VERT = 1,
+	INFOFRAME_AVI_DB1B_HORI = 2,
+	INFOFRAME_AVI_DB1B_VERTHORI = 3,
+	INFOFRAME_AVI_DB1S_0 = 0,
+	INFOFRAME_AVI_DB1S_1 = 1,
+	INFOFRAME_AVI_DB1S_2 = 2,
+	INFOFRAME_AVI_DB2C_NO = 0,
+	INFOFRAME_AVI_DB2C_ITU601 = 1,
+	INFOFRAME_AVI_DB2C_ITU709 = 2,
+	INFOFRAME_AVI_DB2C_EC_EXTENDED = 3,
+	INFOFRAME_AVI_DB2M_NO = 0,
+	INFOFRAME_AVI_DB2M_43 = 1,
+	INFOFRAME_AVI_DB2M_169 = 2,
+	INFOFRAME_AVI_DB2R_SAME = 8,
+	INFOFRAME_AVI_DB2R_43 = 9,
+	INFOFRAME_AVI_DB2R_169 = 10,
+	INFOFRAME_AVI_DB2R_149 = 11,
+	INFOFRAME_AVI_DB3ITC_NO = 0,
+	INFOFRAME_AVI_DB3ITC_YES = 1,
+	INFOFRAME_AVI_DB3EC_XVYUV601 = 0,
+	INFOFRAME_AVI_DB3EC_XVYUV709 = 1,
+	INFOFRAME_AVI_DB3Q_DEFAULT = 0,
+	INFOFRAME_AVI_DB3Q_LR = 1,
+	INFOFRAME_AVI_DB3Q_FR = 2,
+	INFOFRAME_AVI_DB3SC_NO = 0,
+	INFOFRAME_AVI_DB3SC_HORI = 1,
+	INFOFRAME_AVI_DB3SC_VERT = 2,
+	INFOFRAME_AVI_DB3SC_HORIVERT = 3,
+	INFOFRAME_AVI_DB5PR_NO = 0,
+	INFOFRAME_AVI_DB5PR_2 = 1,
+	INFOFRAME_AVI_DB5PR_3 = 2,
+	INFOFRAME_AVI_DB5PR_4 = 3,
+	INFOFRAME_AVI_DB5PR_5 = 4,
+	INFOFRAME_AVI_DB5PR_6 = 5,
+	INFOFRAME_AVI_DB5PR_7 = 6,
+	INFOFRAME_AVI_DB5PR_8 = 7,
+	INFOFRAME_AVI_DB5PR_9 = 8,
+	INFOFRAME_AVI_DB5PR_10 = 9
+};
+
+enum hdmi_stereo_channel {
+	HDMI_STEREO_NOCHANNEL = 0,
+	HDMI_STEREO_ONECHANNELS = 1,
+	HDMI_STEREO_TWOCHANNELS = 2,
+	HDMI_STEREO_THREECHANNELS = 3,
+	HDMI_STEREO_FOURCHANNELS = 4
+};
+
+enum hdmi_cea_code {
+	HDMI_CEA_CODE_00 = 0x0,
+	HDMI_CEA_CODE_01 = 0x1,
+	HDMI_CEA_CODE_02 = 0x2,
+	HDMI_CEA_CODE_03 = 0x3,
+	HDMI_CEA_CODE_04 = 0x4,
+	HDMI_CEA_CODE_05 = 0x5,
+	HDMI_CEA_CODE_06 = 0x6,
+	HDMI_CEA_CODE_07 = 0x7,
+	HDMI_CEA_CODE_08 = 0x8,
+	HDMI_CEA_CODE_09 = 0x9,
+	HDMI_CEA_CODE_0A = 0xA,
+	HDMI_CEA_CODE_0B = 0xB,
+	HDMI_CEA_CODE_0C = 0xC,
+	HDMI_CEA_CODE_0D = 0xD,
+	HDMI_CEA_CODE_0E = 0xE,
+	HDMI_CEA_CODE_0F = 0xF,
+	HDMI_CEA_CODE_10 = 0x10,
+	HDMI_CEA_CODE_11 = 0x11,
+	HDMI_CEA_CODE_12 = 0x12,
+	HDMI_CEA_CODE_13 = 0x13,
+	HDMI_CEA_CODE_14 = 0x14,
+	HDMI_CEA_CODE_15 = 0x15,
+	HDMI_CEA_CODE_16 = 0x16,
+	HDMI_CEA_CODE_17 = 0x17,
+	HDMI_CEA_CODE_18 = 0x18,
+	HDMI_CEA_CODE_19 = 0x19,
+	HDMI_CEA_CODE_1A = 0x1A,
+	HDMI_CEA_CODE_1B = 0x1B,
+	HDMI_CEA_CODE_1C = 0x1C,
+	HDMI_CEA_CODE_1D = 0x1D,
+	HDMI_CEA_CODE_1E = 0x1E,
+	HDMI_CEA_CODE_1F = 0x1F,
+	HDMI_CEA_CODE_20 = 0x20,
+	HDMI_CEA_CODE_21 = 0x21,
+	HDMI_CEA_CODE_22 = 0x22,
+	HDMI_CEA_CODE_23 = 0x23,
+	HDMI_CEA_CODE_24 = 0x24,
+	HDMI_CEA_CODE_25 = 0x25,
+	HDMI_CEA_CODE_26 = 0x26
+};
+
+enum hdmi_iec_format {
+	HDMI_AUDIO_FORMAT_LPCM = 0,
+	HDMI_AUDIO_FORMAT_IEC = 1
+};
+
+enum hdmi_audio_justify {
+	HDMI_AUDIO_JUSTIFY_LEFT = 0,
+	HDMI_AUDIO_JUSTIFY_RIGHT = 1
+};
+
+enum hdmi_sample_order {
+	HDMI_SAMPLE_RIGHT_FIRST = 0,
+	HDMI_SAMPLE_LEFT_FIRST = 1
+};
+
+enum hdmi_sample_perword {
+	HDMI_ONEWORD_ONE_SAMPLE = 0,
+	HDMI_ONEWORD_TWO_SAMPLES = 1
+};
+
+enum hdmi_sample_size {
+	HDMI_SAMPLE_16BITS = 0,
+	HDMI_SAMPLE_24BITS = 1
+};
+
+enum hdmi_dma_irq {
+	HDMI_THRESHOLD_DMA = 0,
+	HDMI_THRESHOLD_IRQ = 1
+};
+
+enum hdmi_block_start_end {
+	HDMI_BLOCK_STARTEND_ON = 0,
+	HDMI_BLOCK_STARTEND_OFF = 1
+};
+
+
+enum hdmi_core_if_fs {
+	IF_FS_NO = 0x0,
+	IF_FS_32000 = 0x1,
+	IF_FS_44100 = 0x2,
+	IF_FS_48000 = 0x3,
+	IF_FS_88200 = 0x4,
+	IF_FS_96000 = 0x5,
+	IF_FS_176400 = 0x6,
+	IF_FS_192000 = 0x7
+};
+
+enum hdmi_core_if_sample_size {
+	IF_NO_PER_SAMPLE = 0x0,
+	IF_16BIT_PER_SAMPLE = 0x1,
+	IF_20BIT_PER_SAMPLE = 0x2,
+	IF_24BIT_PER_SAMPLE = 0x3
+};
+
+
+enum hdmi_packing_mode {
+	HDMI_PACK_10b_RGB_YUV444 = 0,
+	HDMI_PACK_24b_RGB_YUV444_YUV422 = 1,
+	HDMI_PACK_20b_YUV422 = 2,
+	HDMI_PACK_ALREADYPACKED = 7
+};
+
+
+struct hdmi_core_video_config {
+	enum hdmi_core_inputbus_width	ip_bus_width;
+	enum hdmi_core_dither_trunc	op_dither_truc;
+	enum hdmi_core_deepcolor_ed	deep_color_pkt;
+	enum hdmi_core_packet_mode	pkt_mode;
+	enum hdmi_core_hdmi_dvi		hdmi_dvi;
+	enum hdmi_core_tclkselclkmult	tclk_sel_clkmult;
+};
+
+/*
+ * Refer to section 8.2 in HDMI 1.3 specification for
+ * details about infoframe databytes
+ */
+struct hdmi_core_infoframe_avi {
+	u8	db1_format;
+		/* Y0, Y1 rgb,yCbCr */
+	u8	db1_active_info;
+		/* A0  Active information Present */
+	u8	db1_bar_info_dv;
+		/* B0, B1 Bar info data valid */
+	u8	db1_scan_info;
+		/* S0, S1 scan information */
+	u8	db2_colorimetry;
+		/* C0, C1 colorimetry */
+	u8	db2_aspect_ratio;
+		/* M0, M1 Aspect ratio (4:3, 16:9) */
+	u8	db2_active_fmt_ar;
+		/* R0...R3 Active format aspect ratio */
+	u8	db3_itc;
+		/* ITC IT content. */
+	u8	db3_ec;
+		/* EC0, EC1, EC2 Extended colorimetry */
+	u8	db3_q_range;
+		/* Q1, Q0 Quantization range */
+	u8	db3_nup_scaling;
+		/* SC1, SC0 Non-uniform picture scaling */
+	u8	db4_videocode;
+		/* VIC0..6 Video format identification */
+	u8	db5_pixel_repeat;
+		/* PR0..PR3 Pixel repetition factor */
+	u16	db6_7_line_eoftop;
+		/* Line number end of top bar */
+	u16	db8_9_line_sofbottom;
+		/* Line number start of bottom bar */
+	u16	db10_11_pixel_eofleft;
+		/* Pixel number end of left bar */
+	u16	db12_13_pixel_sofright;
+		/* Pixel number start of right bar */
+};
+
+struct hdmi_core_packet_enable_repeat {
+	u32	audio_pkt;
+	u32	audio_pkt_repeat;
+	u32	avi_infoframe;
+	u32	avi_infoframe_repeat;
+	u32	gen_cntrl_pkt;
+	u32	gen_cntrl_pkt_repeat;
+	u32	generic_pkt;
+	u32	generic_pkt_repeat;
+};
+
+struct hdmi_audio_format {
+	enum hdmi_stereo_channel	stereo_channel_enable;
+	enum hdmi_cea_code		audio_channel_location;
+	enum hdmi_iec_format		iec;
+	enum hdmi_audio_justify		justify;
+	enum hdmi_sample_order		left_before;
+	enum hdmi_sample_perword	sample_number;
+	enum hdmi_sample_size		sample_size;
+};
+
+
+struct hdmi_audio_dma {
+	u8				dma_transfer;
+	u8				block_size;
+	enum hdmi_dma_irq		dma_or_irq;
+	u16				threshold_value;
+	enum hdmi_block_start_end	block_start_end;
+};
+
+struct hdmi_video_format {
+	enum hdmi_packing_mode	packing_mode;
+	u32			y_res;	/* Line per panel */
+	u32			x_res;	/* pixel per line */
+};
+
+struct hdmi_video_interface {
+	int	vsp;	/* Vsync polarity */
+	int	hsp;	/* Hsync polarity */
+	int	interlacing;
+	int	tm;	/* Timing mode */
+};
+
+struct hdmi_video_timing {
+	u32	hbp;
+	u32	hfp;
+	u32	hsw;
+	u32	vbp;
+	u32	vfp;
+	u32	vsw;
+};
+
+struct hdmi_config {
+	u16	ppl;	/* pixel per line */
+	u16	lpp;	/* line per panel */
+	u32	pixel_clock;
+	u16	hsw;	/* Horizontal sync pulse width */
+	u16	hfp;	/* Horizontal front porch */
+	u16	hbp;	/* Horizontal back porch */
+	u16	vsw;	/* Vertical sync pulse width */
+	u16	vfp;	/* Vertical front porch */
+	u16	vbp;	/* Vertical back porch */
+	u16	interlace;
+	u16	h_pol;
+	u16	v_pol;
+	u16	hdmi_dvi;
+	u16	video_format;
+};
+
+struct hdmi_core_audio_config {
+	enum hdmi_core_fs		fs; /* 0=32KHz - 1=44.1KHz */
+	u32				n;
+	u32				cts;
+	u32				aud_par_busclk;
+	enum hdmi_core_layout		layout; /* 0: 2Ch - 1: 8Ch */
+	enum hdmi_core_cts_mode		cts_mode; /* 0: HW  - 1: SW*/
+	enum hdmi_core_if_fs		if_fs;
+	u32				if_channel_number;
+	enum hdmi_core_if_sample_size	if_sample_size;
+	enum hdmi_cea_code		if_audio_channel_location;
+};
+
+struct hdmi_cm {
+	int	code;
+	int	mode;
+};
+
+struct hdmi_irq_vector {
+	u8	pll_recal;
+	u8	pll_unlock;
+	u8	pll_lock;
+	u8	phy_disconnect;
+	u8	phy_connect;
+	u8	phy_short_5v;
+	u8	video_end_fr;
+	u8	video_vsync;
+	u8	fifo_sample_req;
+	u8	fifo_overflow;
+	u8	fifo_underflow;
+	u8	ocp_timeout;
+	u8	core;
+};
+
+#endif
-- 
1.5.6.3


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 5/8] OMAP4 : DSS2 : HDMI: HDMI driver addition in the DSS drivers interface
  2011-02-25 14:21 [PATCH 0/8] OMAP4 : DSS2 : HDMI support Mythri P K
                   ` (3 preceding siblings ...)
  2011-02-25 14:21 ` [PATCH 4/8] OMAP4 : DSS : HDMI: HDMI driver header file addition Mythri P K
@ 2011-02-25 14:21 ` Mythri P K
  2011-02-27 10:17   ` Tomi Valkeinen
  2011-02-25 14:21 ` [PATCH 6/8] OMAP4 : DSS2 : HDMI: HDMI panel driver addition in the DSS Mythri P K
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 23+ messages in thread
From: Mythri P K @ 2011-02-25 14:21 UTC (permalink / raw)
  To: linux-omap; +Cc: tomi.valkeinen, Mythri P K

Adding the hdmi interface driver(hdmi.c) to the dss driver.
It configures the audio and video portion of HDMI in the
display header file to be accessed by the panels.

Signed-off-by: Mythri P K <mythripk@ti.com>
---
 drivers/video/omap2/dss/Kconfig   |    8 +
 drivers/video/omap2/dss/Makefile  |    1 +
 drivers/video/omap2/dss/display.c |    3 +
 drivers/video/omap2/dss/dss.h     |   33 +
 drivers/video/omap2/dss/hdmi.c    | 1276 +++++++++++++++++++++++++++++++++++++
 drivers/video/omap2/dss/hdmi.h    |    9 +
 6 files changed, 1330 insertions(+), 0 deletions(-)
 create mode 100644 drivers/video/omap2/dss/hdmi.c

diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index 0d031b2..fe1ab09 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -60,6 +60,14 @@ config OMAP2_DSS_VENC
 	help
 	  OMAP Video Encoder support for S-Video and composite TV-out.
 
+config OMAP2_DSS_HDMI
+	bool "HDMI support"
+	depends on ARCH_OMAP4
+        default n
+	help
+	  HDMI Interface. This adds the High Definition Multimedia Interface.
+	  See http://www.hdmi.org/ for HDMI specification.
+
 config OMAP2_DSS_SDI
 	bool "SDI support"
 	depends on ARCH_OMAP3
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 7db17b5..5998b69 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -5,3 +5,4 @@ omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
 omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
 omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
 omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
+omapdss-$(CONFIG_OMAP2_DSS_HDMI) += hdmi.o
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index e10b303..cbab61a 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -447,6 +447,9 @@ void dss_init_device(struct platform_device *pdev,
 		r = dsi_init_display(dssdev);
 		break;
 #endif
+	case OMAP_DISPLAY_TYPE_HDMI:
+		r = hdmi_init_display(dssdev);
+		break;
 	default:
 		BUG();
 	}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index d199ba7..171877e 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -163,6 +163,16 @@ struct dsi_clock_info {
 	bool use_dss2_fck;
 };
 
+/* HDMI PLL structure */
+struct hdmi_pll_info {
+	u16 regn;
+	u16 regm;
+	u32 regmf;
+	u16 regm2;
+	u16 regsd;
+	u16 dcofreq;
+};
+
 struct seq_file;
 struct platform_device;
 
@@ -428,6 +438,29 @@ static inline void venc_uninit_platform_driver(void)
 }
 #endif
 
+/* HDMI */
+#ifdef CONFIG_OMAP2_DSS_HDMI
+int hdmi_init_platform_driver(void);
+void hdmi_uninit_platform_driver(void);
+int hdmi_init_display(struct omap_dss_device *dssdev);
+#else
+static inline int hdmi_init_display(struct omap_dss_device *dssdev)
+{
+	return 0;
+}
+static inline int hdmi_init_platform_driver(void)
+{
+	return 0;
+}
+static inline void hdmi_uninit_platform_driver(void)
+{
+}
+#endif
+int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
+void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
+int omapdss_hdmi_display_suspend(struct omap_dss_device *dssdev);
+int omapdss_hdmi_display_resume(struct omap_dss_device *dssdev);
+
 /* RFBI */
 #ifdef CONFIG_OMAP2_DSS_RFBI
 int rfbi_init_platform_driver(void);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
new file mode 100644
index 0000000..1cd861f
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -0,0 +1,1276 @@
+/*
+ * 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 <plat/display.h>
+
+#include "dss.h"
+#include "hdmi.h"
+
+static struct {
+	struct mutex lock;
+	struct omap_display_platform_data *pdata;
+	struct platform_device *pdev;
+	void __iomem *base_wp;	/* HDMI wrapper */
+	int code;
+	int mode;
+	struct hdmi_config cfg;
+} hdmi;
+
+static inline void hdmi_write_reg(const struct hdmi_reg idx, u32 val)
+{
+	__raw_writel(val, hdmi.base_wp + idx.idx);
+}
+
+static inline u32 hdmi_read_reg(const struct hdmi_reg idx)
+{
+	u32 l;
+	l = __raw_readl(hdmi.base_wp + idx.idx);
+	return l;
+}
+
+static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx,
+				int b2, int b1, u32 val)
+{
+	u32 t = 0;
+	while (val != FLD_GET(hdmi_read_reg(idx), b2, b1)) {
+		udelay(1);
+		if (t++ > 10000)
+			return !val;
+	}
+	return val;
+}
+
+int hdmi_init_display(struct omap_dss_device *dssdev)
+{
+	DSSDBG("init_display\n");
+
+	return 0;
+}
+
+static int hdmi_pll_init(int refsel, int dcofreq,
+		struct hdmi_pll_info *fmt, u16 sd)
+{
+	u32 r;
+
+	/* PLL start always use manual mode */
+	REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
+
+	r = hdmi_read_reg(PLLCTRL_CFG1);
+	r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
+	r = FLD_MOD(r, fmt->regn, 8, 1);  /* CFG1_PLL_REGN */
+
+	hdmi_write_reg(PLLCTRL_CFG1, r);
+
+	r = hdmi_read_reg(PLLCTRL_CFG2);
+
+	r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
+	r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
+	r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
+
+	if (dcofreq) {
+		/* divider programming for frequency beyond 1000Mhz */
+		REG_FLD_MOD(PLLCTRL_CFG3, sd, 17, 10);
+		r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
+	} else {
+		r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
+	}
+
+	hdmi_write_reg(PLLCTRL_CFG2, r);
+
+	r = hdmi_read_reg(PLLCTRL_CFG4);
+	r = FLD_MOD(r, fmt->regm2, 24, 18);
+	r = FLD_MOD(r, fmt->regmf, 17, 0);
+
+	hdmi_write_reg(PLLCTRL_CFG4, r);
+
+	/* go now */
+	REG_FLD_MOD(PLLCTRL_PLL_GO, 0x1, 0, 0);
+
+	/* wait for bit change */
+	if (hdmi_wait_for_bit_change(PLLCTRL_PLL_GO, 0, 0, 1) != 1) {
+		DSSERR("PLL GO bit not set\n");
+		return -ETIMEDOUT;
+	}
+
+	/* Wait till the lock bit is set in PLL status */
+	if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
+		DSSWARN("cannot lock PLL\n");
+		DSSWARN("CFG1 0x%x\n",
+			hdmi_read_reg(PLLCTRL_CFG1));
+		DSSWARN("CFG2 0x%x\n",
+			hdmi_read_reg(PLLCTRL_CFG2));
+		DSSWARN("CFG4 0x%x\n",
+			hdmi_read_reg(PLLCTRL_CFG4));
+		return -ETIMEDOUT;
+	}
+
+	DSSDBG("PLL locked!\n");
+
+	return 0;
+}
+
+static int hdmi_pll_reset(void)
+{
+	/* SYSRESET  controlled by power FSM */
+	REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 3, 3);
+
+	/* READ 0x0 reset is in progress */
+	if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) {
+		DSSERR("Failed to sysreset PLL\n");
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static int hdmi_phy_init(void)
+{
+	u16 r = 0;
+
+	/*
+	 * wait till PHY_PWR_STATUS=LDOON
+	 * HDMI_PHYPWRCMD_LDOON = 1
+	 */
+	r = hdmi_wait_phy_pwr(1);
+	if (r)
+		return r;
+
+	/* wait till PHY_PWR_STATUS=TXON */
+	r = hdmi_wait_phy_pwr(2);
+	if (r)
+		return r;
+
+	/*
+	 * Read address 0 in order to get the SCP reset done completed
+	 * Dummy access performed to make sure reset is done
+	 */
+	hdmi_read_reg(HDMI_TXPHY_TX_CTRL);
+
+	/*
+	 * Write to phy address 0 to configure the clock
+	 * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field
+	 */
+	REG_FLD_MOD(HDMI_TXPHY_TX_CTRL, 0x1, 31, 30);
+
+	/* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */
+	hdmi_write_reg(HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
+
+	/* Setup max LDO voltage */
+	REG_FLD_MOD(HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
+
+	/* Write to phy address 3 to change the polarity control */
+	REG_FLD_MOD(HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
+
+	return 0;
+}
+
+int hdmi_pll_program(struct hdmi_pll_info *fmt)
+{
+	u16 r = 0;
+	int refsel;
+
+	/* wait for wrapper reset */
+	hdmi_wait_softreset();
+
+	/* power off PLL */
+	r = hdmi_wait_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
+	if (r)
+		return r;
+
+	/* power on PLL */
+	r = hdmi_wait_pll_pwr(HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
+	if (r)
+		return r;
+
+	hdmi_pll_reset();
+
+	refsel = 0x3; /* select SYSCLK reference */
+
+	r = hdmi_pll_init(refsel, fmt->dcofreq, fmt, fmt->regsd);
+	if (r)
+		return r;
+
+	return 0;
+}
+
+static void hdmi_phy_off(void)
+{
+	/*
+	 * Wait till PHY_PWR_STATUS=OFF
+	 * HDMI_PHYPWRCMD_OFF = 0
+	 */
+	hdmi_wait_phy_pwr(0);
+}
+
+int hdmi_core_ddc_edid(u8 *pEDID, int ext)
+{
+	u32 i, j, l;
+	char checksum = 0;
+	u32 offset = 0;
+
+	/* Turn on CLK for DDC */
+	REG_FLD_MOD(HDMI_CORE_AV_DPD, 0x7, 2, 0);
+
+	/* HACK : DDC needs time to stablize */
+	mdelay(10);
+
+	if (!ext) {
+		/* Clk SCL Devices */
+		REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0xA, 3, 0);
+
+		/* HDMI_CORE_DDC_STATUS_IN_PROG No timer needed */
+		if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
+						4, 4, 0) != 0) {
+			DSSERR("Failed to program DDC\n");
+			return -ETIMEDOUT;
+		}
+
+		/* Clear FIFO */
+		REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x9, 3, 0);
+
+		/* HDMI_CORE_DDC_STATUS_IN_PROG */
+		if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
+						4, 4, 0) != 0) {
+			DSSERR("Failed to program DDC\n");
+			return -ETIMEDOUT;
+		}
+
+	} else {
+		if (ext % 2 != 0)
+			offset = 0x80;
+	}
+
+	/* Load Segment Address Register */
+	REG_FLD_MOD(HDMI_CORE_DDC_SEGM, ext/2, 7, 0);
+
+	/* Load Slave Address Register */
+	REG_FLD_MOD(HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
+
+	/* Load Offset Address Register */
+	REG_FLD_MOD(HDMI_CORE_DDC_OFFSET, offset, 7, 0);
+
+	/* Load Byte Count */
+	REG_FLD_MOD(HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
+	REG_FLD_MOD(HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
+
+	/* Set DDC_CMD */
+	if (ext)
+		REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x4, 3, 0);
+	else
+		REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x2, 3, 0);
+
+	/*
+	 * Do not optimize this part of the code, seems
+	 * DDC bus needs some time to get stabilized
+	 */
+	l = hdmi_read_reg(HDMI_CORE_DDC_STATUS);
+
+	/* HDMI_CORE_DDC_STATUS_BUS_LOW */
+	if (FLD_GET(l, 6, 6) == 1) {
+		DSSWARN("I2C Bus Low?\n");
+		return -EIO;
+	}
+	/* HDMI_CORE_DDC_STATUS_NO_ACK */
+	if (FLD_GET(l, 5, 5) == 1) {
+		DSSWARN("I2C No Ack\n");
+		return -EIO;
+	}
+
+	i = ext * 128;
+	j = 0;
+	while (((FLD_GET(hdmi_read_reg(HDMI_CORE_DDC_STATUS), 4, 4) == 1) ||
+		(FLD_GET(hdmi_read_reg(HDMI_CORE_DDC_STATUS), 2, 2) == 0)) &&
+								j < 128) {
+		if (FLD_GET(hdmi_read_reg(HDMI_CORE_DDC_STATUS), 2, 2) == 0) {
+			/* FIFO not empty */
+			pEDID[i++] = FLD_GET(
+				hdmi_read_reg(HDMI_CORE_DDC_DATA), 7, 0);
+			j++;
+		}
+	}
+
+	for (j = 0; j < 128; j++)
+		checksum += pEDID[j];
+
+	if (checksum != 0) {
+		DSSERR("E-EDID checksum failed!!\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int read_edid(u8 *pEDID, u16 max_length)
+{
+	int r = 0, n = 0, i = 0;
+	int max_ext_blocks = (max_length / 128) - 1;
+
+	r = hdmi_core_ddc_edid(pEDID, 0);
+	if (r) {
+		return -EIO;
+	} else {
+		n = pEDID[0x7e];
+
+		/*
+		 * README: need to comply with max_length set by the caller.
+		 * Better implementation should be to allocate necessary
+		 * memory to store EDID according to nb_block field found
+		 * in first block
+		 */
+
+		if (n > max_ext_blocks)
+			n = max_ext_blocks;
+
+		for (i = 1; i <= n; i++) {
+			r = hdmi_core_ddc_edid(pEDID, i);
+			if (r)
+				return -EIO;
+		}
+	}
+	return 0;
+}
+
+static inline void print_omap_video_timings(struct omap_video_timings *timings)
+{
+	DSSINFO("Timing Info:\n");
+	DSSINFO("pixel_clk = %d\n", timings->pixel_clock);
+	DSSINFO("  x_res     = %d\n", timings->x_res);
+	DSSINFO("  y_res     = %d\n", timings->y_res);
+	DSSINFO("  hfp       = %d\n", timings->hfp);
+	DSSINFO("  hsw       = %d\n", timings->hsw);
+	DSSINFO("  hbp       = %d\n", timings->hbp);
+	DSSINFO("  vfp       = %d\n", timings->vfp);
+	DSSINFO("  vsw       = %d\n", timings->vsw);
+	DSSINFO("  vbp       = %d\n", timings->vbp);
+}
+
+static int get_timings_index(void)
+{
+	int code;
+
+	if (hdmi.mode == 0)
+		code = code_vesa[hdmi.code];
+	else
+		code = code_cea[hdmi.code];
+
+	if (code == -1)	{
+		code = 9;
+		/* HDMI code 16 corresponds to 1920 * 1080 */
+		hdmi.code = 16;
+		/* HDMI mode 1 corresponds to HDMI 0 to DVI */
+		hdmi.mode = HDMI_HDMI;
+	}
+	return code;
+}
+
+static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
+{
+	int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0;
+	int timing_vsync = 0, timing_hsync = 0;
+	struct omap_video_timings temp;
+	struct hdmi_cm cm = {-1};
+	DSSDBG("hdmi_get_code\n");
+
+	for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) {
+		temp = cea_vesa_timings[i].timings;
+		if ((temp.pixel_clock == timing->pixel_clock) &&
+			(temp.x_res == timing->x_res) &&
+			(temp.y_res == timing->y_res)) {
+
+			temp_hsync = temp.hfp + temp.hsw + temp.hbp;
+			timing_hsync = timing->hfp + timing->hsw + timing->hbp;
+			temp_vsync = temp.vfp + temp.vsw + temp.vbp;
+			timing_vsync = timing->vfp + timing->vsw + timing->vbp;
+
+			DSSDBG("temp_hsync = %d , temp_vsync = %d"
+				"timing_hsync = %d, timing_vsync = %d\n",
+				temp_hsync, temp_hsync,
+				timing_hsync, timing_vsync);
+
+			if ((temp_hsync == timing_hsync) &&
+					(temp_vsync == timing_vsync)) {
+				code = i;
+				cm.code = code_index[i];
+				if (code < 14)
+					cm.mode = HDMI_HDMI;
+				else
+					cm.mode = HDMI_DVI;
+				DSSINFO("Hdmi_code = %d mode = %d\n",
+					 cm.code, cm.mode);
+				print_omap_video_timings(&temp);
+				break;
+			 }
+		}
+	}
+
+	return cm;
+}
+
+void get_horz_vert_timing_info(int current_descriptor_addrs, u8 *edid ,
+		struct omap_video_timings *timings)
+{
+	/* X and Y resolution */
+	timings->x_res = (((edid[current_descriptor_addrs + 4] & 0xF0) << 4) |
+			 edid[current_descriptor_addrs + 2]);
+	timings->y_res = (((edid[current_descriptor_addrs + 7] & 0xF0) << 4) |
+			 edid[current_descriptor_addrs + 5]);
+
+	timings->pixel_clock = ((edid[current_descriptor_addrs + 1] << 8) |
+				edid[current_descriptor_addrs]);
+
+	timings->pixel_clock = 10 * timings->pixel_clock;
+
+	/* HORIZONTAL FRONT PORCH */
+	timings->hfp = edid[current_descriptor_addrs + 8] |
+			((edid[current_descriptor_addrs + 11] & 0xc0) << 2);
+	/* HORIZONTAL SYNC WIDTH */
+	timings->hsw = edid[current_descriptor_addrs + 9] |
+			((edid[current_descriptor_addrs + 11] & 0x30) << 4);
+	/* HORIZONTAL BACK PORCH */
+	timings->hbp = (((edid[current_descriptor_addrs + 4] & 0x0F) << 8) |
+			edid[current_descriptor_addrs + 3]) -
+			(timings->hfp + timings->hsw);
+	/* VERTICAL FRONT PORCH */
+	timings->vfp = ((edid[current_descriptor_addrs + 10] & 0xF0) >> 4) |
+			((edid[current_descriptor_addrs + 11] & 0x0f) << 2);
+	/* VERTICAL SYNC WIDTH */
+	timings->vsw = (edid[current_descriptor_addrs + 10] & 0x0F) |
+			((edid[current_descriptor_addrs + 11] & 0x03) << 4);
+	/* VERTICAL BACK PORCH */
+	timings->vbp = (((edid[current_descriptor_addrs + 7] & 0x0F) << 8) |
+			edid[current_descriptor_addrs + 6]) -
+			(timings->vfp + timings->vsw);
+
+	print_omap_video_timings(timings);
+
+}
+
+/* Description : This function gets the resolution information from EDID */
+static void get_edid_timing_data(u8 *edid)
+{
+	u8 count, code;
+	u16 current_descriptor_addrs;
+	struct hdmi_cm cm;
+
+	/* seach block 0, there are 4 DTDs arranged in priority order */
+	for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) {
+		current_descriptor_addrs =
+			EDID_DESCRIPTOR_BLOCK0_ADDRESS +
+			count * EDID_TIMING_DESCRIPTOR_SIZE;
+		get_horz_vert_timing_info(current_descriptor_addrs,
+				edid, &edid_timings);
+		cm = hdmi_get_code(&edid_timings);
+		DSSINFO("Block0[%d] value matches code = %d , mode = %d\n",
+			count, cm.code, cm.mode);
+		if (cm.code == -1) {
+			continue;
+		} else {
+			hdmi.code = cm.code;
+			hdmi.mode = cm.mode;
+			DSSINFO("code = %d , mode = %d\n",
+				hdmi.code, hdmi.mode);
+			return;
+		}
+	}
+	if (edid[0x7e] != 0x00) {
+		for (count = 0; count < EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR;
+			count++) {
+			current_descriptor_addrs =
+			EDID_DESCRIPTOR_BLOCK1_ADDRESS +
+			count * EDID_TIMING_DESCRIPTOR_SIZE;
+			get_horz_vert_timing_info(current_descriptor_addrs,
+						edid, &edid_timings);
+			cm = hdmi_get_code(&edid_timings);
+			DSSINFO("Block1[%d] value matches code = %d, mode = %d",
+				count, cm.code, cm.mode);
+			if (cm.code == -1) {
+				continue;
+			} else {
+				hdmi.code = cm.code;
+				hdmi.mode = cm.mode;
+				DSSINFO("code = %d , mode = %d\n",
+					hdmi.code, hdmi.mode);
+				return;
+			}
+		}
+	}
+
+	DSSINFO("no valid timing found , falling back to VGA\n");
+	hdmi.code = 4; /* setting default value of 640 480 VGA */
+	hdmi.mode = HDMI_DVI;
+	code = code_vesa[hdmi.code];
+	edid_timings = cea_vesa_timings[code].timings;
+}
+
+static int hdmi_read_edid(struct omap_video_timings *dp)
+{
+	int ret = 0, code;
+
+	memset(edid, 0, HDMI_EDID_MAX_LENGTH);
+
+	if (!edid_set)
+		ret = read_edid(edid, HDMI_EDID_MAX_LENGTH);
+
+	if (ret != 0) {
+		DSSWARN("failed to read E-EDID\n");
+	} else {
+		if (!memcmp(edid, header, sizeof(header))) {
+			/* search for timings of default resolution */
+			get_edid_timing_data(edid);
+			edid_set = true;
+		}
+	}
+
+	if (!edid_set) {
+		DSSINFO("fallback to VGA\n");
+		hdmi.code = 4; /* setting default value of 640 480 VGA */
+		hdmi.mode = HDMI_DVI;
+	}
+
+	code = get_timings_index();
+
+	*dp = cea_vesa_timings[code].timings;
+
+	DSSDBG("print EDID timings\n");
+	print_omap_video_timings(dp);
+
+	return 0;
+}
+
+static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
+			struct hdmi_core_infoframe_avi *avi_cfg,
+			struct hdmi_core_packet_enable_repeat *repeat_cfg)
+{
+	DSSDBG("Enter hdmi_core_init\n");
+
+	/* video core */
+	video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
+	video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT;
+	video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE;
+	video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
+	video_cfg->hdmi_dvi = HDMI_DVI;
+	video_cfg->tclk_sel_clkmult = FPLL10IDCK;
+
+	/* info frame */
+	avi_cfg->db1_format = 0;
+	avi_cfg->db1_active_info = 0;
+	avi_cfg->db1_bar_info_dv = 0;
+	avi_cfg->db1_scan_info = 0;
+	avi_cfg->db2_colorimetry = 0;
+	avi_cfg->db2_aspect_ratio = 0;
+	avi_cfg->db2_active_fmt_ar = 0;
+	avi_cfg->db3_itc = 0;
+	avi_cfg->db3_ec = 0;
+	avi_cfg->db3_q_range = 0;
+	avi_cfg->db3_nup_scaling = 0;
+	avi_cfg->db4_videocode = 0;
+	avi_cfg->db5_pixel_repeat = 0;
+	avi_cfg->db6_7_line_eoftop = 0 ;
+	avi_cfg->db8_9_line_sofbottom = 0;
+	avi_cfg->db10_11_pixel_eofleft = 0;
+	avi_cfg->db12_13_pixel_sofright = 0;
+
+	/* packet enable and repeat */
+	repeat_cfg->audio_pkt = 0;
+	repeat_cfg->audio_pkt_repeat = 0;
+	repeat_cfg->avi_infoframe = 0;
+	repeat_cfg->avi_infoframe_repeat = 0;
+	repeat_cfg->gen_cntrl_pkt = 0;
+	repeat_cfg->gen_cntrl_pkt_repeat = 0;
+	repeat_cfg->generic_pkt = 0;
+	repeat_cfg->generic_pkt_repeat = 0;
+}
+
+static void hdmi_core_powerdown_disable(void)
+{
+	DSSDBG("Enter hdmi_core_powerdown_disable\n");
+	REG_FLD_MOD(HDMI_CORE_CTRL1, 0x0, 0, 0);
+}
+
+static void hdmi_core_swreset_release(void)
+{
+	DSSDBG("Enter hdmi_core_swreset_release\n");
+	REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x0, 0, 0);
+}
+
+static void hdmi_core_swreset_assert(void)
+{
+	DSSDBG("Enter hdmi_core_swreset_assert\n");
+	REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x1, 0, 0);
+}
+
+/* DSS_HDMI_CORE_VIDEO_CONFIG */
+static void hdmi_core_video_config(struct hdmi_core_video_config *cfg)
+{
+	u32 r = 0;
+
+	/* sys_ctrl1 default configuration not tunable */
+	r = hdmi_read_reg(HDMI_CORE_CTRL1);
+	r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5);
+	r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4);
+	r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2);
+	r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1);
+	hdmi_write_reg(HDMI_CORE_CTRL1, r);
+
+	REG_FLD_MOD(HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
+
+	/* Vid_Mode */
+	r = hdmi_read_reg(HDMI_CORE_SYS_VID_MODE);
+
+	/* dither truncation configuration */
+	if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) {
+		r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6);
+		r = FLD_MOD(r, 1, 5, 5);
+	} else {
+		r = FLD_MOD(r, cfg->op_dither_truc, 7, 6);
+		r = FLD_MOD(r, 0, 5, 5);
+	}
+	hdmi_write_reg(HDMI_CORE_SYS_VID_MODE, r);
+
+	/* HDMI_Ctrl */
+	r = hdmi_read_reg(HDMI_CORE_AV_HDMI_CTRL);
+	r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);
+	r = FLD_MOD(r, cfg->pkt_mode, 5, 3);
+	r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0);
+	hdmi_write_reg(HDMI_CORE_AV_HDMI_CTRL, r);
+
+	/* TMDS_CTRL */
+	REG_FLD_MOD(HDMI_CORE_SYS_TMDS_CTRL,
+		cfg->tclk_sel_clkmult, 6, 5);
+}
+
+static void hdmi_core_aux_infoframe_avi_config(
+		struct hdmi_core_infoframe_avi info_avi)
+{
+	u32 val;
+	char sum = 0, checksum = 0;
+
+	sum += 0x82 + 0x002 + 0x00D;
+	hdmi_write_reg(HDMI_CORE_AV_AVI_TYPE, 0x082);
+	hdmi_write_reg(HDMI_CORE_AV_AVI_VERS, 0x002);
+	hdmi_write_reg(HDMI_CORE_AV_AVI_LEN, 0x00D);
+
+	val = (info_avi.db1_format << 5) |
+		(info_avi.db1_active_info << 4) |
+		(info_avi.db1_bar_info_dv << 2) |
+		(info_avi.db1_scan_info);
+	hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(0), val);
+	sum += val;
+
+	val = (info_avi.db2_colorimetry << 6) |
+		(info_avi.db2_aspect_ratio << 4) |
+		(info_avi.db2_active_fmt_ar);
+	hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(1), val);
+	sum += val;
+
+	val = (info_avi.db3_itc << 7) |
+		(info_avi.db3_ec << 4) |
+		(info_avi.db3_q_range << 2) |
+		(info_avi.db3_nup_scaling);
+	hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(2), val);
+	sum += val;
+
+	hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(3), info_avi.db4_videocode);
+	sum += info_avi.db4_videocode;
+
+	val = info_avi.db5_pixel_repeat;
+	hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(4), val);
+	sum += val;
+
+	val = info_avi.db6_7_line_eoftop & 0x00FF;
+	hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(5), val);
+	sum += val;
+
+	val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
+	hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(6), val);
+	sum += val;
+
+	val = info_avi.db8_9_line_sofbottom & 0x00FF;
+	hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(7), val);
+	sum += val;
+
+	val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
+	hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(8), val);
+	sum += val;
+
+	val = info_avi.db10_11_pixel_eofleft & 0x00FF;
+	hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(9), val);
+	sum += val;
+
+	val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
+	hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(10), val);
+	sum += val;
+
+	val = info_avi.db12_13_pixel_sofright & 0x00FF;
+	hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(11), val);
+	sum += val;
+
+	val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
+	hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(12), val);
+	sum += val;
+
+	checksum = 0x100 - sum;
+	hdmi_write_reg(HDMI_CORE_AV_AVI_CHSUM, checksum);
+}
+
+static void hdmi_core_av_packet_config(
+		struct hdmi_core_packet_enable_repeat repeat_cfg)
+{
+	/* enable/repeat the infoframe */
+	hdmi_write_reg(HDMI_CORE_AV_PB_CTRL1,
+		(repeat_cfg.audio_pkt << 5)|
+		(repeat_cfg.audio_pkt_repeat << 4)|
+		(repeat_cfg.avi_infoframe << 1)|
+		(repeat_cfg.avi_infoframe_repeat));
+
+	/* enable/repeat the packet */
+	hdmi_write_reg(HDMI_CORE_AV_PB_CTRL2,
+		(repeat_cfg.gen_cntrl_pkt << 3)|
+		(repeat_cfg.gen_cntrl_pkt_repeat << 2)|
+		(repeat_cfg.generic_pkt << 1)|
+		(repeat_cfg.generic_pkt_repeat));
+}
+
+static void hdmi_wp_init(struct hdmi_video_timing *timings,
+			struct hdmi_video_format *video_fmt,
+			struct hdmi_video_interface *video_int)
+{
+	DSSDBG("Enter hdmi_wp_init\n");
+
+	timings->hbp = 0;
+	timings->hfp = 0;
+	timings->hsw = 0;
+	timings->vbp = 0;
+	timings->vfp = 0;
+	timings->vsw = 0;
+
+	video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
+	video_fmt->y_res = 0;
+	video_fmt->x_res = 0;
+
+	video_int->vsp = 0;
+	video_int->hsp = 0;
+
+	video_int->interlacing = 0;
+	video_int->tm = 0; /* HDMI_TIMING_SLAVE */
+
+}
+
+/* PHY_PWR_CMD */
+int hdmi_wait_phy_pwr(int val)
+{
+	REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 7, 6);
+
+	if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 5, 4, val) != val) {
+		DSSERR("Failed to set PHY power mode to %d\n", val);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+/* PLL_PWR_CMD */
+int hdmi_wait_pll_pwr(int val)
+{
+	REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 3, 2);
+
+	/* wait till PHY_PWR_STATUS=ON */
+	if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 1, 0, val) != val) {
+		DSSERR("Failed to set PHY_PWR_STATUS to ON\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+void hdmi_wp_video_stop(void)
+{
+	REG_FLD_MOD(HDMI_WP_VIDEO_CFG, 0, 31, 31);
+}
+
+void hdmi_wp_video_start(void)
+{
+	REG_FLD_MOD(HDMI_WP_VIDEO_CFG, (u32)0x1, 31, 31);
+}
+
+static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
+	struct hdmi_video_timing *timings, struct hdmi_config *param)
+{
+	DSSDBG("Enter hdmi_wp_video_init_format\n");
+
+	video_fmt->y_res = param->lpp;
+	video_fmt->x_res = param->ppl;
+
+	timings->hbp = param->hbp;
+	timings->hfp = param->hfp;
+	timings->hsw = param->hsw;
+	timings->vbp = param->vbp;
+	timings->vfp = param->vfp;
+	timings->vsw = param->vsw;
+}
+
+static void hdmi_wp_video_config_format(
+		struct hdmi_video_format *video_fmt)
+{
+	u32 l = 0;
+
+	REG_FLD_MOD(HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, 10, 8);
+
+	l |= FLD_VAL(video_fmt->y_res, 31, 16);
+	l |= FLD_VAL(video_fmt->x_res, 15, 0);
+	hdmi_write_reg(HDMI_WP_VIDEO_SIZE, l);
+}
+
+static void hdmi_wp_video_config_interface(
+		struct hdmi_video_interface *video_int)
+{
+	u32 r;
+	DSSDBG("Enter hdmi_wp_video_config_interface\n");
+
+	r = hdmi_read_reg(HDMI_WP_VIDEO_CFG);
+	r = FLD_MOD(r, video_int->vsp, 7, 7);
+	r = FLD_MOD(r, video_int->hsp, 6, 6);
+	r = FLD_MOD(r, video_int->interlacing, 3, 3);
+	r = FLD_MOD(r, video_int->tm, 1, 0);
+	hdmi_write_reg(HDMI_WP_VIDEO_CFG, r);
+}
+
+static void hdmi_wp_video_config_timing(
+		struct hdmi_video_timing *timings)
+{
+	u32 timing_h = 0;
+	u32 timing_v = 0;
+
+	DSSDBG("Enter hdmi_wp_video_config_timing\n");
+
+	timing_h |= FLD_VAL(timings->hbp, 31, 20);
+	timing_h |= FLD_VAL(timings->hfp, 19, 8);
+	timing_h |= FLD_VAL(timings->hsw, 7, 0);
+	hdmi_write_reg(HDMI_WP_VIDEO_TIMING_H, timing_h);
+
+	timing_v |= FLD_VAL(timings->vbp, 31, 20);
+	timing_v |= FLD_VAL(timings->vfp, 19, 8);
+	timing_v |= FLD_VAL(timings->vsw, 7, 0);
+	hdmi_write_reg(HDMI_WP_VIDEO_TIMING_V, timing_v);
+}
+
+void hdmi_lib_enable(struct hdmi_config *cfg)
+{
+	/* HDMI */
+	struct hdmi_video_timing video_timing;
+	struct hdmi_video_format video_format;
+	struct hdmi_video_interface video_interface;
+	/* HDMI core */
+	struct hdmi_core_infoframe_avi avi_cfg;
+	struct hdmi_core_video_config v_core_cfg;
+	struct hdmi_core_packet_enable_repeat repeat_cfg;
+
+	hdmi_wp_init(&video_timing, &video_format,
+		&video_interface);
+
+	hdmi_core_init(&v_core_cfg,
+		&avi_cfg,
+		&repeat_cfg);
+
+	/* init DSS register */
+	hdmi_wp_video_init_format(&video_format,
+			&video_timing, cfg);
+
+	hdmi_wp_video_config_timing(&video_timing);
+
+	/* video config */
+	video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422;
+
+	hdmi_wp_video_config_format(&video_format);
+
+	video_interface.vsp = cfg->v_pol;
+	video_interface.hsp = cfg->h_pol;
+	video_interface.interlacing = cfg->interlace;
+	video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
+
+	hdmi_wp_video_config_interface(&video_interface);
+
+	/*
+	 * configure core video part
+	 * set software reset in the core
+	 */
+	hdmi_core_swreset_assert();
+
+	/* power down off */
+	hdmi_core_powerdown_disable();
+
+	v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
+	v_core_cfg.hdmi_dvi = cfg->hdmi_dvi;
+
+	hdmi_core_video_config(&v_core_cfg);
+
+	/* release software reset in the core */
+	hdmi_core_swreset_release();
+
+	/*
+	 * configure packet
+	 * info frame video see doc CEA861-D page 65
+	 */
+	avi_cfg.db1_format = INFOFRAME_AVI_DB1Y_RGB;
+	avi_cfg.db1_active_info =
+		INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
+	avi_cfg.db1_bar_info_dv = INFOFRAME_AVI_DB1B_NO;
+	avi_cfg.db1_scan_info = INFOFRAME_AVI_DB1S_0;
+	avi_cfg.db2_colorimetry = INFOFRAME_AVI_DB2C_NO;
+	avi_cfg.db2_aspect_ratio = INFOFRAME_AVI_DB2M_NO;
+	avi_cfg.db2_active_fmt_ar = INFOFRAME_AVI_DB2R_SAME;
+	avi_cfg.db3_itc = INFOFRAME_AVI_DB3ITC_NO;
+	avi_cfg.db3_ec = INFOFRAME_AVI_DB3EC_XVYUV601;
+	avi_cfg.db3_q_range = INFOFRAME_AVI_DB3Q_DEFAULT;
+	avi_cfg.db3_nup_scaling = INFOFRAME_AVI_DB3SC_NO;
+	avi_cfg.db4_videocode = cfg->video_format;
+	avi_cfg.db5_pixel_repeat = INFOFRAME_AVI_DB5PR_NO;
+	avi_cfg.db6_7_line_eoftop = 0;
+	avi_cfg.db8_9_line_sofbottom = 0;
+	avi_cfg.db10_11_pixel_eofleft = 0;
+	avi_cfg.db12_13_pixel_sofright = 0;
+
+	hdmi_core_aux_infoframe_avi_config(avi_cfg);
+
+	/* enable/repeat the infoframe */
+	repeat_cfg.avi_infoframe = PACKETENABLE;
+	repeat_cfg.avi_infoframe_repeat = PACKETREPEATON;
+
+	/* wakeup */
+	repeat_cfg.audio_pkt = PACKETENABLE;
+	repeat_cfg.audio_pkt_repeat = PACKETREPEATON;
+	hdmi_core_av_packet_config(repeat_cfg);
+}
+
+static void update_hdmi_timings(struct hdmi_config *cfg,
+		struct omap_video_timings *timings, int code)
+{
+	cfg->ppl = timings->x_res;
+	cfg->lpp = timings->y_res;
+	cfg->hbp = timings->hbp;
+	cfg->hfp = timings->hfp;
+	cfg->hsw = timings->hsw;
+	cfg->vbp = timings->vbp;
+	cfg->vfp = timings->vfp;
+	cfg->vsw = timings->vsw;
+	cfg->pixel_clock = timings->pixel_clock;
+	cfg->v_pol = cea_vesa_timings[code].vsync_pol;
+	cfg->h_pol = cea_vesa_timings[code].hsync_pol;
+}
+
+void hdmi_lib_exit(void)
+{
+
+}
+
+int hdmi_wait_softreset(void)
+{
+	/* reset W1 */
+	REG_FLD_MOD(HDMI_WP_SYSCONFIG, 0x1, 0, 0);
+
+	/* wait till SOFTRESET == 0 */
+	if (hdmi_wait_for_bit_change(HDMI_WP_SYSCONFIG, 0, 0, 0) != 0) {
+		DSSERR("sysconfig reset failed\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+void hdmi_compute_pll(unsigned long clkin, int phy,
+	int n, struct hdmi_pll_info *pi)
+{
+	unsigned long refclk;
+	u32 mf;
+
+	/*
+	 * Input clock is predivided by N + 1
+	 * out put of which is reference clk
+	 */
+	refclk = clkin / (n + 1);
+	pi->regn = n;
+
+	/*
+	 * multiplier is pixel_clk/ref_clk
+	 * Multiplying by 100 to avoid fractional part removal
+	 */
+	pi->regm = (phy * 100/(refclk))/100;
+	pi->regm2 = 1;
+
+	/*
+	 * fractional multiplier is remainder of the difference between
+	 * multiplier and actual phy(required pixel clock thus should be
+	 * multiplied by 2^18(262144) divided by the reference clock
+	 */
+	mf = (phy - pi->regm * refclk) * 262144;
+	pi->regmf = mf/(refclk);
+
+	/*
+	 * Dcofreq should be set to 1 if required pixel clock
+	 * is greater than 1000MHz
+	 */
+	pi->dcofreq = phy > 1000 * 100;
+	pi->regsd = ((pi->regm * clkin / 10) / ((n + 1) * 250) + 5) / 10;
+
+	DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
+	DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
+}
+
+static void hdmi_enable_clocks(int enable)
+{
+	if (enable)
+		dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK |
+				DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
+	else
+		dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK |
+				DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
+}
+
+static int hdmi_power_on(struct omap_dss_device *dssdev)
+{
+	int r, code = 0;
+	struct hdmi_pll_info pll_data;
+	struct omap_video_timings *p;
+	int clkin, n, phy;
+
+	hdmi_enable_clocks(1);
+
+	dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
+
+	p = &dssdev->panel.timings;
+
+	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
+		dssdev->panel.timings.x_res,
+		dssdev->panel.timings.y_res);
+
+	DSSDBG("Read EDID as no EDID is not set on poweron\n");
+	r = hdmi_read_edid(p);
+	if (r)
+		return -EIO;
+
+	code = get_timings_index();
+	dssdev->panel.timings = cea_vesa_timings[code].timings;
+	update_hdmi_timings(&hdmi.cfg, p, code);
+
+	clkin = 3840; /* 38.4 MHz */
+	n = 15; /* this is a constant for our math */
+	phy = p->pixel_clock;
+
+	hdmi_compute_pll(clkin, phy, n, &pll_data);
+
+	hdmi_wp_video_stop();
+
+	/* config the PLL and PHY first */
+	r = hdmi_pll_program(&pll_data);
+	if (r) {
+		DSSDBG("Failed to lock PLL\n");
+		return -EIO;
+	}
+
+	r = hdmi_phy_init();
+	if (r) {
+		DSSDBG("Failed to start PHY\n");
+		return -EIO;
+	}
+
+	hdmi.cfg.hdmi_dvi = hdmi.mode;
+	hdmi.cfg.video_format = hdmi.code;
+	hdmi_lib_enable(&hdmi.cfg);
+
+	/* these settings are independent of overlays */
+	dss_select_hdmi_venc(1);
+
+	/* bypass TV gamma table */
+	dispc_enable_gamma_table(0);
+
+	/* tv size */
+	dispc_set_digit_size(dssdev->panel.timings.x_res,
+			dssdev->panel.timings.y_res);
+
+	dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 1);
+
+	hdmi_wp_video_start();
+
+	return 0;
+}
+
+static void hdmi_power_off(struct omap_dss_device *dssdev)
+{
+	dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
+
+	hdmi_wp_video_stop();
+	hdmi_phy_off();
+	hdmi_wait_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
+	hdmi_enable_clocks(0);
+
+	edid_set = 0;
+}
+
+int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
+{
+	int r = 0;
+
+	DSSDBG("ENTER hdmi_display_enable\n");
+
+	mutex_lock(&hdmi.lock);
+
+	r = omap_dss_start_device(dssdev);
+	if (r) {
+		DSSDBG("failed to start device\n");
+		goto err;
+	}
+
+	if (dssdev->platform_enable)
+		dssdev->platform_enable(dssdev);
+
+	r = hdmi_power_on(dssdev);
+	if (r) {
+		DSSERR("failed to power on device\n");
+		goto err;
+	}
+
+err:
+	mutex_unlock(&hdmi.lock);
+
+	return r;
+}
+
+void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
+{
+	DSSDBG("Enter hdmi_display_disable\n");
+
+	mutex_lock(&hdmi.lock);
+
+	omap_dss_stop_device(dssdev);
+
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
+
+	hdmi_power_off(dssdev);
+
+	mutex_unlock(&hdmi.lock);
+}
+
+int omapdss_hdmi_display_suspend(struct omap_dss_device *dssdev)
+{
+	DSSDBG("hdmi_display_suspend\n");
+
+	mutex_lock(&hdmi.lock);
+
+	omap_dss_stop_device(dssdev);
+
+	hdmi_power_off(dssdev);
+
+	mutex_unlock(&hdmi.lock);
+
+	return 0;
+}
+
+int omapdss_hdmi_display_resume(struct omap_dss_device *dssdev)
+{
+	int r = 0;
+
+	DSSDBG("hdmi_display_resume\n");
+
+	mutex_lock(&hdmi.lock);
+
+	r = omap_dss_start_device(dssdev);
+	if (r) {
+		DSSERR("failed to start device\n");
+		goto err;
+	}
+
+	if (dssdev->platform_enable)
+		dssdev->platform_enable(dssdev);
+
+	r = hdmi_power_on(dssdev);
+	if (r) {
+		DSSERR("failed to power on device\n");
+		goto err;
+	}
+
+err:
+	mutex_unlock(&hdmi.lock);
+
+	return r;
+}
+
+/* HDMI HW IP initialisation */
+static int omap_hdmihw_probe(struct platform_device *pdev)
+{
+	struct resource *hdmi_mem;
+
+	hdmi.pdata = pdev->dev.platform_data;
+	hdmi.pdev = pdev;
+
+	mutex_init(&hdmi.lock);
+
+	hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0);
+	if (!hdmi_mem) {
+		DSSERR("can't get IORESOURCE_MEM HDMI\n");
+		return -EINVAL;
+	}
+
+	/* Base address taken from platform */
+	hdmi.base_wp = ioremap(hdmi_mem->start, resource_size(hdmi_mem));
+	if (!hdmi.base_wp) {
+		DSSERR("can't ioremap WP\n");
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static int omap_hdmihw_remove(struct platform_device *pdev)
+{
+	iounmap(hdmi.base_wp);
+
+	return 0;
+}
+
+static struct platform_driver omap_hdmihw_driver = {
+	.probe          = omap_hdmihw_probe,
+	.remove         = omap_hdmihw_remove,
+	.driver         = {
+		.name   = "omap_hdmi",
+		.owner  = THIS_MODULE,
+	},
+};
+
+int hdmi_init_platform_driver(void)
+{
+	return platform_driver_register(&omap_hdmihw_driver);
+}
+
+void hdmi_uninit_platform_driver(void)
+{
+	return platform_driver_unregister(&omap_hdmihw_driver);
+}
diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h
index 7441835..40f98f9 100644
--- a/drivers/video/omap2/dss/hdmi.h
+++ b/drivers/video/omap2/dss/hdmi.h
@@ -688,4 +688,13 @@ struct hdmi_irq_vector {
 	u8	core;
 };
 
+/* Function prototype */
+int hdmi_wait_phy_pwr(int param);
+int hdmi_wait_pll_pwr(int param);
+int hdmi_wait_softreset(void);
+int hdmi_core_ddc_edid(u8 *data, int ext);
+void hdmi_lib_enable(struct hdmi_config *cfg);
+int hdmi_lib_init(void);
+void hdmi_lib_exit(void);
+
 #endif
-- 
1.5.6.3


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 6/8] OMAP4 : DSS2 : HDMI: HDMI panel driver addition in the DSS
  2011-02-25 14:21 [PATCH 0/8] OMAP4 : DSS2 : HDMI support Mythri P K
                   ` (4 preceding siblings ...)
  2011-02-25 14:21 ` [PATCH 5/8] OMAP4 : DSS2 : HDMI: HDMI driver addition in the DSS drivers interface Mythri P K
@ 2011-02-25 14:21 ` Mythri P K
  2011-02-27  9:43   ` Tomi Valkeinen
  2011-02-25 14:21 ` [PATCH 7/8] OMAP4 : DSS : HDMI: Call to HDMI module init to register driver Mythri P K
  2011-02-25 14:21 ` [PATCH 8/8] OMAP4 : DSS2 : Add display structure in the board file for OMAP4 pandaboard Mythri P K
  7 siblings, 1 reply; 23+ messages in thread
From: Mythri P K @ 2011-02-25 14:21 UTC (permalink / raw)
  To: linux-omap; +Cc: tomi.valkeinen, Mythri P K

The panel driver(hdmi_omap4_panel.c) in dss file acts as a controller
to manage the enable and disable requests and synchronize audio and video.
Also the header file to export the hdmi registers is added in the
plat-omap , so that it can be accessed by audio driver.

Signed-off-by: Mythri P K <mythripk@ti.com>
---
 drivers/video/omap2/dss/Kconfig            |    8 ++
 drivers/video/omap2/dss/Makefile           |    1 +
 drivers/video/omap2/dss/hdmi_omap4_panel.c |  190 ++++++++++++++++++++++++++++
 3 files changed, 199 insertions(+), 0 deletions(-)
 create mode 100644 drivers/video/omap2/dss/hdmi_omap4_panel.c

diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index fe1ab09..670a55d 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -125,4 +125,12 @@ config OMAP2_DSS_MIN_FCK_PER_PCK
 	  Max FCK is 173MHz, so this doesn't work if your PCK
 	  is very high.
 
+config OMAP4_PANEL_HDMI
+	bool "HDMI panel support"
+	depends on OMAP2_DSS_HDMI
+        default n
+	help
+	  HDMI panel. This adds the High Definition Multimedia panel.
+	  See http://www.hdmi.org/ for HDMI specification.
+
 endif
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 5998b69..95234d4 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -6,3 +6,4 @@ omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
 omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
 omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
 omapdss-$(CONFIG_OMAP2_DSS_HDMI) += hdmi.o
+obj-$(CONFIG_OMAP4_PANEL_HDMI) += hdmi_omap4_panel.o
diff --git a/drivers/video/omap2/dss/hdmi_omap4_panel.c b/drivers/video/omap2/dss/hdmi_omap4_panel.c
new file mode 100644
index 0000000..c28b1f6
--- /dev/null
+++ b/drivers/video/omap2/dss/hdmi_omap4_panel.c
@@ -0,0 +1,190 @@
+/*
+ * hdmi_omap4_panel.c
+ *
+ * HDMI library support functions for TI OMAP4 processors.
+ *
+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Authors:	MythriPk <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/err.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <plat/display.h>
+
+#include "dss.h"
+
+static struct {
+	struct mutex hdmi_lock;
+} hdmi;
+
+
+static int hdmi_panel_probe(struct omap_dss_device *dssdev)
+{
+	DSSDBG("ENTER hdmi_panel_probe\n");
+
+	dssdev->panel.config = OMAP_DSS_LCD_TFT |
+			OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS;
+
+	/*
+	 * Initialize the timings to 1920 * 1080
+	 * This is only for framebuffer update not for TV timing setting
+	 * Setting TV timing will be done only on enable
+	 */
+	dssdev->panel.timings.x_res = 1920;
+	dssdev->panel.timings.y_res = 1080;
+
+	DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
+		dssdev->panel.timings.x_res,
+		dssdev->panel.timings.y_res);
+	return 0;
+}
+
+static void hdmi_panel_remove(struct omap_dss_device *dssdev)
+{
+
+}
+
+static int hdmi_panel_enable(struct omap_dss_device *dssdev)
+{
+	int r = 0;
+	DSSDBG("ENTER hdmi_panel_enable\n");
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)
+		return -EINVAL;
+
+	mutex_lock(&hdmi.hdmi_lock);
+
+	r = omapdss_hdmi_display_enable(dssdev);
+	if (r) {
+		DSSERR("failed to power on\n");
+		return r;
+	}
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	mutex_unlock(&hdmi.hdmi_lock);
+
+	return 0;
+}
+
+static void hdmi_panel_disable(struct omap_dss_device *dssdev)
+{
+	mutex_lock(&hdmi.hdmi_lock);
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
+		omapdss_hdmi_display_disable(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+
+	mutex_unlock(&hdmi.hdmi_lock);
+}
+
+static int hdmi_panel_suspend(struct omap_dss_device *dssdev)
+{
+	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED ||
+			dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED)
+		return -EINVAL;
+
+	mutex_lock(&hdmi.hdmi_lock);
+
+	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+
+	omapdss_hdmi_display_suspend(dssdev);
+
+	mutex_unlock(&hdmi.hdmi_lock);
+
+	return 0;
+}
+
+static int hdmi_panel_resume(struct omap_dss_device *dssdev)
+{
+	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
+		return -EINVAL;
+
+	mutex_lock(&hdmi.hdmi_lock);
+
+	omapdss_hdmi_display_resume(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	mutex_unlock(&hdmi.hdmi_lock);
+
+	return 0;
+}
+
+static void hdmi_get_timings(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings)
+{
+	*timings = dssdev->panel.timings;
+}
+
+static void hdmi_set_timings(struct omap_dss_device *dssdev,
+			struct omap_video_timings *timings)
+{
+	DSSDBG("hdmi_set_timings\n");
+
+	dssdev->panel.timings = *timings;
+
+	mutex_lock(&hdmi.hdmi_lock);
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
+		/* turn the hdmi off and on to get new timings to use */
+		omapdss_hdmi_display_disable(dssdev);
+		omapdss_hdmi_display_enable(dssdev);
+	}
+
+	mutex_unlock(&hdmi.hdmi_lock);
+}
+
+static struct omap_dss_driver hdmi_driver = {
+	.probe		= hdmi_panel_probe,
+	.remove		= hdmi_panel_remove,
+	.enable		= hdmi_panel_enable,
+	.disable	= hdmi_panel_disable,
+	.suspend	= hdmi_panel_suspend,
+	.resume		= hdmi_panel_resume,
+	.get_timings	= hdmi_get_timings,
+	.set_timings	= hdmi_set_timings,
+	.driver			= {
+		.name   = "hdmi_panel",
+		.owner  = THIS_MODULE,
+	},
+};
+
+static int __init hdmi_panel_init(void)
+{
+	mutex_init(&hdmi.hdmi_lock);
+
+	omap_dss_register_driver(&hdmi_driver);
+
+	return 0;
+}
+
+static void __exit hdmi_panel_exit(void)
+{
+	omap_dss_unregister_driver(&hdmi_driver);
+
+}
+
+module_init(hdmi_panel_init);
+module_exit(hdmi_panel_exit);
-- 
1.5.6.3


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 7/8] OMAP4 : DSS : HDMI: Call to HDMI module init to register driver.
  2011-02-25 14:21 [PATCH 0/8] OMAP4 : DSS2 : HDMI support Mythri P K
                   ` (5 preceding siblings ...)
  2011-02-25 14:21 ` [PATCH 6/8] OMAP4 : DSS2 : HDMI: HDMI panel driver addition in the DSS Mythri P K
@ 2011-02-25 14:21 ` Mythri P K
  2011-02-25 14:21 ` [PATCH 8/8] OMAP4 : DSS2 : Add display structure in the board file for OMAP4 pandaboard Mythri P K
  7 siblings, 0 replies; 23+ messages in thread
From: Mythri P K @ 2011-02-25 14:21 UTC (permalink / raw)
  To: linux-omap; +Cc: tomi.valkeinen, Mythri P K

calling the platform registration of HDMI driver from core during initialization.

Signed-off-by: Mythri P K <mythripk@ti.com>
---
 drivers/video/omap2/dss/core.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 3c4ad3a..e08bfef 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -229,6 +229,12 @@ static int omap_dss_probe(struct platform_device *pdev)
 		}
 	}
 
+	r = hdmi_init_platform_driver();
+	if (r) {
+		DSSERR("Failed to initialize hdmi\n");
+		goto err_hdmi;
+	}
+
 	r = dss_initialize_debugfs();
 	if (r)
 		goto err_debugfs;
@@ -258,6 +264,8 @@ static int omap_dss_probe(struct platform_device *pdev)
 err_register:
 	dss_uninitialize_debugfs();
 err_debugfs:
+	hdmi_uninit_platform_driver();
+err_hdmi:
 	if (cpu_is_omap34xx())
 		dsi_uninit_platform_driver();
 err_dsi:
-- 
1.5.6.3


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 8/8] OMAP4 : DSS2 : Add display structure in the board file for OMAP4 pandaboard
  2011-02-25 14:21 [PATCH 0/8] OMAP4 : DSS2 : HDMI support Mythri P K
                   ` (6 preceding siblings ...)
  2011-02-25 14:21 ` [PATCH 7/8] OMAP4 : DSS : HDMI: Call to HDMI module init to register driver Mythri P K
@ 2011-02-25 14:21 ` Mythri P K
  7 siblings, 0 replies; 23+ messages in thread
From: Mythri P K @ 2011-02-25 14:21 UTC (permalink / raw)
  To: linux-omap; +Cc: tomi.valkeinen, Mythri P K

Adding  board file structure for display which adds the display
structure with HDMI as the default driver when the display init
is called.
HDMI GPIO configurations are also done in this file.

Signed-off-by: Mythri P K <mythripk@ti.com>
---
 arch/arm/mach-omap2/board-omap4panda.c |   82 ++++++++++++++++++++++++++++++++
 1 files changed, 82 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index e944025..86ec234 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -32,6 +32,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+#include <plat/display.h>
 
 #include <plat/board.h>
 #include <plat/common.h>
@@ -45,6 +46,8 @@
 
 #define GPIO_HUB_POWER		1
 #define GPIO_HUB_NRESET		62
+#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
+#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
 
 static struct gpio_led gpio_leds[] = {
 	{
@@ -397,6 +400,84 @@ static struct omap_board_mux board_mux[] __initdata = {
 #define board_mux	NULL
 #endif
 
+static void sdp4430_hdmi_mux_init(void)
+{
+	/* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
+	omap_mux_init_signal("hdmi_hpd",
+			OMAP_PIN_INPUT_PULLUP);
+	omap_mux_init_signal("hdmi_cec",
+			OMAP_PIN_INPUT_PULLUP);
+	/* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
+	omap_mux_init_signal("hdmi_ddc_scl",
+			OMAP_PIN_INPUT_PULLUP);
+	omap_mux_init_signal("hdmi_ddc_sda",
+			OMAP_PIN_INPUT_PULLUP);
+}
+
+static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
+{
+	int status;
+
+	status = gpio_request_one(HDMI_GPIO_HPD, GPIOF_DIR_OUT,
+							"hdmi_gpio_hpd");
+	if (status) {
+		pr_err("Cannot request GPIO %d\n", HDMI_GPIO_HPD);
+		return status;
+	}
+	status = gpio_request_one(HDMI_GPIO_LS_OE, GPIOF_DIR_OUT,
+							"hdmi_gpio_ls_oe");
+	if (status) {
+		pr_err("Cannot request GPIO %d\n", HDMI_GPIO_LS_OE);
+		goto error1;
+	}
+
+	/* The value set a pulse */
+	gpio_set_value(HDMI_GPIO_HPD, 1);
+	gpio_set_value(HDMI_GPIO_LS_OE, 1);
+	gpio_set_value(HDMI_GPIO_HPD, 0);
+	gpio_set_value(HDMI_GPIO_LS_OE, 0);
+	gpio_set_value(HDMI_GPIO_HPD, 1);
+	gpio_set_value(HDMI_GPIO_LS_OE, 1);
+
+	return 0;
+
+error1:
+	gpio_free(HDMI_GPIO_HPD);
+
+	return status;
+}
+
+static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
+{
+	gpio_free(HDMI_GPIO_LS_OE);
+	gpio_free(HDMI_GPIO_HPD);
+}
+
+static struct omap_dss_device sdp4430_hdmi_device = {
+	.name = "hdmi",
+	.driver_name = "hdmi_panel",
+	.type = OMAP_DISPLAY_TYPE_HDMI,
+	.platform_enable = sdp4430_panel_enable_hdmi,
+	.platform_disable = sdp4430_panel_disable_hdmi,
+	.channel = OMAP_DSS_CHANNEL_DIGIT,
+};
+
+static struct omap_dss_device *sdp4430_dss_devices[] = {
+	&sdp4430_hdmi_device,
+};
+
+static struct omap_dss_board_info sdp4430_dss_data = {
+	.num_devices	= ARRAY_SIZE(sdp4430_dss_devices),
+	.devices	= sdp4430_dss_devices,
+	.default_device	= &sdp4430_hdmi_device,
+};
+
+void omap_panda_display_init(void)
+{
+	sdp4430_hdmi_mux_init();
+	omap_display_init(&sdp4430_dss_data);
+}
+
 static void __init omap4_panda_init(void)
 {
 	int package = OMAP_PACKAGE_CBS;
@@ -411,6 +492,7 @@ static void __init omap4_panda_init(void)
 	omap4_twl6030_hsmmc_init(mmc);
 	omap4_ehci_init();
 	usb_musb_init(&musb_board_data);
+	omap_panda_display_init();
 }
 
 static void __init omap4_panda_map_io(void)
-- 
1.5.6.3


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/8] OMAP4 : DSS2 : Add display structure in the board file for OMAP4 sdp
  2011-02-25 14:21 ` [PATCH 2/8] OMAP4 : DSS2 : Add display structure in the board file for OMAP4 sdp Mythri P K
@ 2011-02-27  9:13   ` Tomi Valkeinen
  2011-02-28  5:32     ` K, Mythri P
  0 siblings, 1 reply; 23+ messages in thread
From: Tomi Valkeinen @ 2011-02-27  9:13 UTC (permalink / raw)
  To: K, Mythri P; +Cc: linux-omap@vger.kernel.org

On Fri, 2011-02-25 at 08:21 -0600, K, Mythri P wrote:
> Adding  board file changes for display which adds the display structure
> with HDMI as the default driver when the display init is called.
> HDMI GPIO configurations are also done in this file.
> 
> Signed-off-by: Mythri P K <mythripk@ti.com>
> ---
>  arch/arm/mach-omap2/board-4430sdp.c |   82 +++++++++++++++++++++++++++++++++++
>  1 files changed, 82 insertions(+), 0 deletions(-)

You could move this patch in the end of the set, together with the panda
board patch.

The prefix "OMAP4: DSS2" is not quite right for this, as this is a board
file change. And you should mention HDMI in the subject. Perhaps
something like "OMAP: 4430SDP: Add HDMI support"

> 
> diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
> index 07d1b20..334b6fd 100644
> --- a/arch/arm/mach-omap2/board-4430sdp.c
> +++ b/arch/arm/mach-omap2/board-4430sdp.c
> @@ -35,6 +35,7 @@
>  #include <plat/common.h>
>  #include <plat/usb.h>
>  #include <plat/mmc.h>
> +#include <plat/display.h>
>  
>  #include "mux.h"
>  #include "hsmmc.h"
> @@ -47,6 +48,8 @@
>  #define OMAP4SDP_MDM_PWR_EN_GPIO	157
>  #define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO	184
>  #define OMAP4_SFH7741_ENABLE_GPIO		188
> +#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
> +#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
>  
>  static struct gpio_led sdp4430_gpio_leds[] = {
>  	{
> @@ -552,6 +555,84 @@ static void __init omap_sfh7741prox_init(void)
>  	}
>  }
>  
> +static void sdp4430_hdmi_mux_init(void)
> +{
> +	/* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
> +	omap_mux_init_signal("hdmi_hpd",
> +			OMAP_PIN_INPUT_PULLUP);
> +	omap_mux_init_signal("hdmi_cec",
> +			OMAP_PIN_INPUT_PULLUP);
> +	/* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
> +	omap_mux_init_signal("hdmi_ddc_scl",
> +			OMAP_PIN_INPUT_PULLUP);
> +	omap_mux_init_signal("hdmi_ddc_sda",
> +			OMAP_PIN_INPUT_PULLUP);
> +}
> +
> +static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
> +{
> +	int status;

r is quite often used as a name for return values.

> +
> +	status = gpio_request_one(HDMI_GPIO_HPD, GPIOF_DIR_OUT,
> +							"hdmi_gpio_hpd");
> +	if (status) {
> +		pr_err("Cannot request GPIO %d\n", HDMI_GPIO_HPD);
> +		return status;
> +	}
> +	status = gpio_request_one(HDMI_GPIO_LS_OE, GPIOF_DIR_OUT,
> +							"hdmi_gpio_ls_oe");
> +	if (status) {
> +		pr_err("Cannot request GPIO %d\n", HDMI_GPIO_LS_OE);
> +		goto error1;
> +	}
> +
> +	/* The value set a pulse */

I still don't understand that comment. It's not even English.

 Tomi



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 3/8] OMAP4 : DSS : HDMI: HDMI specific display controller and dss change.
  2011-02-25 14:21 ` [PATCH 3/8] OMAP4 : DSS : HDMI: HDMI specific display controller and dss change Mythri P K
@ 2011-02-27  9:23   ` Tomi Valkeinen
  2011-02-28  6:21     ` K, Mythri P
  0 siblings, 1 reply; 23+ messages in thread
From: Tomi Valkeinen @ 2011-02-27  9:23 UTC (permalink / raw)
  To: K, Mythri P; +Cc: linux-omap@vger.kernel.org

On Fri, 2011-02-25 at 08:21 -0600, K, Mythri P wrote:
> Adding changes to set gamma table bit for TV interface and function to select
> between VENC and HDMI.
> 
> Signed-off-by: Mythri P K <mythripk@ti.com>
> ---
>  drivers/video/omap2/dss/dispc.c |    5 +++++
>  drivers/video/omap2/dss/dss.c   |    7 +++++++
>  drivers/video/omap2/dss/dss.h   |    2 ++
>  3 files changed, 14 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
> index 6d9bb17..16f1106 100644
> --- a/drivers/video/omap2/dss/dispc.c
> +++ b/drivers/video/omap2/dss/dispc.c
> @@ -1213,6 +1213,11 @@ void dispc_enable_zorder(enum omap_plane plane, bool enable)
>  	dispc_write_reg(dispc_reg_att[plane], val);
>  }
>  
> +void dispc_enable_gamma_table(bool enable)
> +{
> +	REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
> +}
> +
>  static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
>  {
>  	u32 val;
> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> index 99de4e1..127d42e 100644
> --- a/drivers/video/omap2/dss/dss.c
> +++ b/drivers/video/omap2/dss/dss.c
> @@ -559,6 +559,13 @@ void dss_set_dac_pwrdn_bgz(bool enable)
>  	REG_FLD_MOD(DSS_CONTROL, enable, 5, 5);	/* DAC Power-Down Control */
>  }
>  
> +void dss_select_hdmi_venc(bool hdmi)
> +{
> +	REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15);	/* 0x1 for HDMI, 0x0 VENC */
> +	if (hdmi)
> +		REG_FLD_MOD(DSS_CONTROL, 0, 9, 8);
> +}

bool argument for this function is very confusing. Which one is true?
Perhaps this could use an enum.

I've tried to keep the habit of having the name of the register field in
comments to make the code easier to read. For example, /*
VENC_HDMI_SWITCH */ for the bit 15.

The bits 8 and 9 are FCK_CLK_SWITCH. Why do you set it here? Looks
rather dangerous to change the clock source like that.

 Tomi




^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 4/8] OMAP4 : DSS : HDMI: HDMI driver header file addition
  2011-02-25 14:21 ` [PATCH 4/8] OMAP4 : DSS : HDMI: HDMI driver header file addition Mythri P K
@ 2011-02-27  9:28   ` Tomi Valkeinen
  2011-02-28  5:40     ` K, Mythri P
  0 siblings, 1 reply; 23+ messages in thread
From: Tomi Valkeinen @ 2011-02-27  9:28 UTC (permalink / raw)
  To: K, Mythri P; +Cc: linux-omap@vger.kernel.org

On Fri, 2011-02-25 at 08:21 -0600, K, Mythri P wrote:
> Adding the hdmi interface driver header file (hdmi.h) to the dss driver.
> Register and timing declaration to be used by the corresponding c file is added in this file.
> 
> Signed-off-by: Mythri P K <mythripk@ti.com>
> ---
>  drivers/video/omap2/dss/hdmi.h |  691 ++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 691 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/video/omap2/dss/hdmi.h
> 
> diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h
> new file mode 100644
> index 0000000..7441835
> --- /dev/null
> +++ b/drivers/video/omap2/dss/hdmi.h
> @@ -0,0 +1,691 @@
> +/*
> + * hdmi.h
> + *
> + * HDMI driver definition for TI OMAP4 processors.
> + *
> + * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.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/>.
> + */
> +
> +#ifndef _HDMI_H_
> +#define _HDMI_H_

This should be more specific. For example, __OMAP2_DSS_HDMI_H would be
in line with the other includes.

> +
> +#include <linux/string.h>
> +#include <plat/display.h>
> +
> +#define HDMI_WP                        0x0
> +#define HDMI_CORE_SYS          0x400
> +#define HDMI_CORE_AV           0x900
> +#define HDMI_PLLCTRL           0x200
> +#define HDMI_PHY               0x300
> +
> +struct hdmi_reg { u16 idx; };
> +
> +#define HDMI_REG(idx)                  ((const struct hdmi_reg) { idx })
> +
> +/* HDMI Wrapper */
> +#define HDMI_WP_REG(idx)                       HDMI_REG(HDMI_WP + idx)
> +
> +#define HDMI_WP_REVISION                       HDMI_WP_REG(0x0)
> +#define HDMI_WP_SYSCONFIG                      HDMI_WP_REG(0x10)
> +#define HDMI_WP_IRQSTATUS_RAW                  HDMI_WP_REG(0x24)
> +#define HDMI_WP_IRQSTATUS                      HDMI_WP_REG(0x28)
> +#define HDMI_WP_PWR_CTRL                       HDMI_WP_REG(0x40)
> +#define HDMI_WP_IRQENABLE_SET                  HDMI_WP_REG(0x2C)
> +#define HDMI_WP_VIDEO_CFG                      HDMI_WP_REG(0x50)
> +#define HDMI_WP_VIDEO_SIZE                     HDMI_WP_REG(0x60)
> +#define HDMI_WP_VIDEO_TIMING_H                 HDMI_WP_REG(0x68)
> +#define HDMI_WP_VIDEO_TIMING_V                 HDMI_WP_REG(0x6C)
> +#define HDMI_WP_WP_CLK                         HDMI_WP_REG(0x70)
> +
> +/* HDMI IP Core System */
> +#define HDMI_CORE_SYS_REG(idx)                 HDMI_REG(HDMI_CORE_SYS + idx)
> +
> +#define HDMI_CORE_SYS_VND_IDL                  HDMI_CORE_SYS_REG(0x0)
> +#define HDMI_CORE_SYS_DEV_IDL                  HDMI_CORE_SYS_REG(0x8)
> +#define HDMI_CORE_SYS_DEV_IDH                  HDMI_CORE_SYS_REG(0xC)
> +#define HDMI_CORE_SYS_DEV_REV                  HDMI_CORE_SYS_REG(0x10)
> +#define HDMI_CORE_SYS_SRST                     HDMI_CORE_SYS_REG(0x14)
> +#define HDMI_CORE_CTRL1                                HDMI_CORE_SYS_REG(0x20)
> +#define HDMI_CORE_SYS_SYS_STAT                 HDMI_CORE_SYS_REG(0x24)
> +#define HDMI_CORE_SYS_VID_ACEN                 HDMI_CORE_SYS_REG(0x124)
> +#define HDMI_CORE_SYS_VID_MODE                 HDMI_CORE_SYS_REG(0x128)
> +#define HDMI_CORE_SYS_INTR_STATE               HDMI_CORE_SYS_REG(0x1C0)
> +#define HDMI_CORE_SYS_INTR1                    HDMI_CORE_SYS_REG(0x1C4)
> +#define HDMI_CORE_SYS_INTR2                    HDMI_CORE_SYS_REG(0x1C8)
> +#define HDMI_CORE_SYS_INTR3                    HDMI_CORE_SYS_REG(0x1CC)
> +#define HDMI_CORE_SYS_INTR4                    HDMI_CORE_SYS_REG(0x1D0)
> +#define HDMI_CORE_SYS_UMASK1                   HDMI_CORE_SYS_REG(0x1D4)
> +#define HDMI_CORE_SYS_TMDS_CTRL                        HDMI_CORE_SYS_REG(0x208)
> +#define HDMI_CORE_SYS_DE_DLY                   HDMI_CORE_SYS_REG(0xC8)
> +#define HDMI_CORE_SYS_DE_CTRL                  HDMI_CORE_SYS_REG(0xCC)
> +#define HDMI_CORE_SYS_DE_TOP                   HDMI_CORE_SYS_REG(0xD0)
> +#define HDMI_CORE_SYS_DE_CNTL                  HDMI_CORE_SYS_REG(0xD8)
> +#define HDMI_CORE_SYS_DE_CNTH                  HDMI_CORE_SYS_REG(0xDC)
> +#define HDMI_CORE_SYS_DE_LINL                  HDMI_CORE_SYS_REG(0xE0)
> +#define HDMI_CORE_SYS_DE_LINH_1                        HDMI_CORE_SYS_REG(0xE4)
> +#define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC                0x1
> +#define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC                0x1
> +#define HDMI_CORE_CTRL1_BSEL_24BITBUS          0x1
> +#define HDMI_CORE_CTRL1_EDGE_RISINGEDGE                0x1
> +
> +/* HDMI DDC E-DID */
> +#define HDMI_CORE_DDC_CMD                      HDMI_CORE_SYS_REG(0x3CC)
> +#define HDMI_CORE_DDC_STATUS                   HDMI_CORE_SYS_REG(0x3C8)
> +#define HDMI_CORE_DDC_ADDR                     HDMI_CORE_SYS_REG(0x3B4)
> +#define HDMI_CORE_DDC_OFFSET                   HDMI_CORE_SYS_REG(0x3BC)
> +#define HDMI_CORE_DDC_COUNT1                   HDMI_CORE_SYS_REG(0x3C0)
> +#define HDMI_CORE_DDC_COUNT2                   HDMI_CORE_SYS_REG(0x3C4)
> +#define HDMI_CORE_DDC_DATA                     HDMI_CORE_SYS_REG(0x3D0)
> +#define HDMI_CORE_DDC_SEGM                     HDMI_CORE_SYS_REG(0x3B8)
> +
> +/* HDMI IP Core Audio Video */
> +#define HDMI_CORE_AV_REG(idx)                  HDMI_REG(HDMI_CORE_AV + idx)
> +
> +#define HDMI_CORE_AV_HDMI_CTRL                 HDMI_CORE_AV_REG(0xBC)
> +#define HDMI_CORE_AV_DPD                       HDMI_CORE_AV_REG(0xF4)
> +#define HDMI_CORE_AV_PB_CTRL1                  HDMI_CORE_AV_REG(0xF8)
> +#define HDMI_CORE_AV_PB_CTRL2                  HDMI_CORE_AV_REG(0xFC)
> +#define HDMI_CORE_AV_AVI_TYPE                  HDMI_CORE_AV_REG(0x100)
> +#define HDMI_CORE_AV_AVI_VERS                  HDMI_CORE_AV_REG(0x104)
> +#define HDMI_CORE_AV_AVI_LEN                   HDMI_CORE_AV_REG(0x108)
> +#define HDMI_CORE_AV_AVI_CHSUM                 HDMI_CORE_AV_REG(0x10C)
> +#define HDMI_CORE_AV_AVI_DBYTE(n)              HDMI_CORE_AV_REG(n * 4 + 0x110)
> +#define HDMI_CORE_AV_AVI_DBYTE_NELEMS          HDMI_CORE_AV_REG(15)
> +#define HDMI_CORE_AV_SPD_DBYTE                 HDMI_CORE_AV_REG(0x190)
> +#define HDMI_CORE_AV_SPD_DBYTE_NELEMS          HDMI_CORE_AV_REG(27)
> +#define HDMI_CORE_AV_MPEG_DBYTE                        HDMI_CORE_AV_REG(0x290)
> +#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS         HDMI_CORE_AV_REG(27)
> +#define HDMI_CORE_AV_GEN_DBYTE                 HDMI_CORE_AV_REG(0x300)
> +#define HDMI_CORE_AV_GEN_DBYTE_NELEMS          HDMI_CORE_AV_REG(31)
> +#define HDMI_CORE_AV_GEN2_DBYTE                        HDMI_CORE_AV_REG(0x380)
> +#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS         HDMI_CORE_AV_REG(31)
> +#define HDMI_CORE_AV_ACR_CTRL                  HDMI_CORE_AV_REG(0x4)
> +#define HDMI_CORE_AV_FREQ_SVAL                 HDMI_CORE_AV_REG(0x8)
> +#define HDMI_CORE_AV_N_SVAL1                   HDMI_CORE_AV_REG(0xC)
> +#define HDMI_CORE_AV_N_SVAL2                   HDMI_CORE_AV_REG(0x10)
> +#define HDMI_CORE_AV_N_SVAL3                   HDMI_CORE_AV_REG(0x14)
> +#define HDMI_CORE_AV_CTS_SVAL1                 HDMI_CORE_AV_REG(0x18)
> +#define HDMI_CORE_AV_CTS_SVAL2                 HDMI_CORE_AV_REG(0x1C)
> +#define HDMI_CORE_AV_CTS_SVAL3                 HDMI_CORE_AV_REG(0x20)
> +#define HDMI_CORE_AV_CTS_HVAL1                 HDMI_CORE_AV_REG(0x24)
> +#define HDMI_CORE_AV_CTS_HVAL2                 HDMI_CORE_AV_REG(0x28)
> +#define HDMI_CORE_AV_CTS_HVAL3                 HDMI_CORE_AV_REG(0x2C)
> +#define HDMI_CORE_AV_AUD_MODE                  HDMI_CORE_AV_REG(0x50)
> +#define HDMI_CORE_AV_SPDIF_CTRL                        HDMI_CORE_AV_REG(0x54)
> +#define HDMI_CORE_AV_HW_SPDIF_FS               HDMI_CORE_AV_REG(0x60)
> +#define HDMI_CORE_AV_SWAP_I2S                  HDMI_CORE_AV_REG(0x64)
> +#define HDMI_CORE_AV_SPDIF_ERTH                        HDMI_CORE_AV_REG(0x6C)
> +#define HDMI_CORE_AV_I2S_IN_MAP                        HDMI_CORE_AV_REG(0x70)
> +#define HDMI_CORE_AV_I2S_IN_CTRL               HDMI_CORE_AV_REG(0x74)
> +#define HDMI_CORE_AV_I2S_CHST0                 HDMI_CORE_AV_REG(0x78)
> +#define HDMI_CORE_AV_I2S_CHST1                 HDMI_CORE_AV_REG(0x7C)
> +#define HDMI_CORE_AV_I2S_CHST2                 HDMI_CORE_AV_REG(0x80)
> +#define HDMI_CORE_AV_I2S_CHST4                 HDMI_CORE_AV_REG(0x84)
> +#define HDMI_CORE_AV_I2S_CHST5                 HDMI_CORE_AV_REG(0x88)
> +#define HDMI_CORE_AV_ASRC                      HDMI_CORE_AV_REG(0x8C)
> +#define HDMI_CORE_AV_I2S_IN_LEN                        HDMI_CORE_AV_REG(0x90)
> +#define HDMI_CORE_AV_HDMI_CTRL                 HDMI_CORE_AV_REG(0xBC)
> +#define HDMI_CORE_AV_AUDO_TXSTAT               HDMI_CORE_AV_REG(0xC0)
> +#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1          HDMI_CORE_AV_REG(0xCC)
> +#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2          HDMI_CORE_AV_REG(0xD0)
> +#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3          HDMI_CORE_AV_REG(0xD4)
> +#define HDMI_CORE_AV_TEST_TXCTRL               HDMI_CORE_AV_REG(0xF0)
> +#define HDMI_CORE_AV_DPD                       HDMI_CORE_AV_REG(0xF4)
> +#define HDMI_CORE_AV_PB_CTRL1                  HDMI_CORE_AV_REG(0xF8)
> +#define HDMI_CORE_AV_PB_CTRL2                  HDMI_CORE_AV_REG(0xFC)
> +#define HDMI_CORE_AV_AVI_TYPE                  HDMI_CORE_AV_REG(0x100)
> +#define HDMI_CORE_AV_AVI_VERS                  HDMI_CORE_AV_REG(0x104)
> +#define HDMI_CORE_AV_AVI_LEN                   HDMI_CORE_AV_REG(0x108)
> +#define HDMI_CORE_AV_AVI_CHSUM                 HDMI_CORE_AV_REG(0x10C)
> +#define HDMI_CORE_AV_SPD_TYPE                  HDMI_CORE_AV_REG(0x180)
> +#define HDMI_CORE_AV_SPD_VERS                  HDMI_CORE_AV_REG(0x184)
> +#define HDMI_CORE_AV_SPD_LEN                   HDMI_CORE_AV_REG(0x188)
> +#define HDMI_CORE_AV_SPD_CHSUM                 HDMI_CORE_AV_REG(0x18C)
> +#define HDMI_CORE_AV_MPEG_TYPE                 HDMI_CORE_AV_REG(0x280)
> +#define HDMI_CORE_AV_MPEG_VERS                 HDMI_CORE_AV_REG(0x284)
> +#define HDMI_CORE_AV_MPEG_LEN                  HDMI_CORE_AV_REG(0x288)
> +#define HDMI_CORE_AV_MPEG_CHSUM                        HDMI_CORE_AV_REG(0x28C)
> +#define HDMI_CORE_AV_CP_BYTE1                  HDMI_CORE_AV_REG(0x37C)
> +#define HDMI_CORE_AV_CEC_ADDR_ID               HDMI_CORE_AV_REG(0x3FC)
> +#define HDMI_CORE_AV_SPD_DBYTE_ELSIZE          0x4
> +#define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE         0x4
> +#define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE         0x4
> +#define HDMI_CORE_AV_GEN_DBYTE_ELSIZE          0x4
> +
> +/* PLL */
> +#define HDMI_PLL_REG(idx)                      HDMI_REG(HDMI_PLLCTRL + idx)
> +
> +#define PLLCTRL_PLL_CONTROL                    HDMI_PLL_REG(0x0)
> +#define PLLCTRL_PLL_STATUS                     HDMI_PLL_REG(0x4)
> +#define PLLCTRL_PLL_GO                         HDMI_PLL_REG(0x8)
> +#define PLLCTRL_CFG1                           HDMI_PLL_REG(0xC)
> +#define PLLCTRL_CFG2                           HDMI_PLL_REG(0x10)
> +#define PLLCTRL_CFG3                           HDMI_PLL_REG(0x14)
> +#define PLLCTRL_CFG4                           HDMI_PLL_REG(0x20)
> +
> +/* HDMI PHY */
> +#define HDMI_PHY_REG(idx)                      HDMI_REG(HDMI_PHY + idx)
> +
> +#define HDMI_TXPHY_TX_CTRL                     HDMI_PHY_REG(0x0)
> +#define HDMI_TXPHY_DIGITAL_CTRL                        HDMI_PHY_REG(0x4)
> +#define HDMI_TXPHY_POWER_CTRL                  HDMI_PHY_REG(0x8)
> +#define HDMI_TXPHY_PAD_CFG_CTRL                        HDMI_PHY_REG(0xC)
> +
> +/* HDMI EDID Length  */
> +#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 REG_FLD_MOD(idx, val, start, end) \
> +       hdmi_write_reg(idx, FLD_MOD(hdmi_read_reg(idx), val, start, end))
> +
> +u8             edid[HDMI_EDID_MAX_LENGTH] = {0};
> +u8             edid_set;
> +u8             header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0};
> +struct         omap_video_timings edid_timings;

Global variables in a header file? This cannot be right.

> +
> +/* HDMI timing structure */
> +struct hdmi_timings {
> +       struct omap_video_timings timings;
> +       int vsync_pol;
> +       int hsync_pol;
> +};
> +
> +/*
> + * Logic for the below structure
> + * user enters the CEA or VESA timings by specifying
> + * the hdmicode which corresponds to CEA/VESA timings
> + * please refer to section 6.3 in HDMI 1.3 specification for timing code.
> + * There is a correspondence between CEA/VESA timing and code.
> + * In the below structure, cea_vesa_timings corresponds to all
> + * The OMAP4 supported timing  CEA and VESA timing values.
> + * code_cea corresponds to the CEA code entered by the user,
> + * The use of it is to get the timing from the cea_vesa_timing array.
> + * Similarly for code_vesa.
> + * code_index is backmapping, Once EDID is read from the TV
> + * EDID is parsed to find the timing values to map it back to the
> + * corresponding CEA or VESA index this structure is used.
> + */
> +
> +/*
> + * This is the structure which has all supported timing
> + * values that OMAP4 supports
> + */
> +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, 112, 64, 256, 6 , 3, 18}, 1, 1},
> +       { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36}, 1, 1},
> +       { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38}, 1, 1},
> +       { {1024, 768, 65000, 136, 24, 160, 6, 3, 29}, 0, 0},
> +       { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32}, 1, 0},
> +       { {1440, 900, 106500, 152, 80, 232, 6, 3, 25}, 1, 0},
> +       { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30}, 1, 0},
> +       { {1366, 768, 85500, 143, 70, 213, 3, 3, 24}, 1, 1},
> +       { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36}, 1, 1},
> +       { {1280, 768, 68250, 32, 48, 80, 7, 3, 12}, 0, 1},
> +       { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23}, 0, 1},
> +       { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21}, 0, 1},
> +       { {1280, 800, 79500, 32, 48, 80, 6, 3, 14}, 0, 1},
> +       { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}
> +};
> +
> +/*
> + * This is a static mapping array which maps the timing values
> + * with corresponding CEA / VESA code
> + */
> +static int code_index[OMAP_HDMI_TIMINGS_NB] = {
> +       1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32,
> +       /* <--15 CEA 17--> vesa*/
> +       4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A,
> +       0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B
> +};
> +
> +/*
> + * This is reverse static mapping which maps the CEA / VESA code
> + * to the corresponding timing values
> + */
> +static int code_cea[39] = {
> +       -1,  0,  3,  3,  2,  8,  5,  5, -1, -1,
> +       -1, -1, -1, -1, -1, -1,  9, 10, 10,  1,
> +       7,   6,  6, -1, -1, -1, -1, -1, -1, 11,
> +       11, 12, 14, -1, -1, 13, 13,  4,  4
> +};
> +
> +int code_vesa[85] = {
> +       -1, -1, -1, -1, 15, -1, -1, -1, -1, 16,
> +       -1, -1, -1, -1, 17, -1, 23, -1, -1, -1,
> +       -1, -1, 29, 18, -1, -1, -1, 32, 19, -1,
> +       -1, -1, 21, -1, -1, 22, -1, -1, -1, 20,
> +       -1, 30, 24, -1, -1, -1, -1, 25, -1, -1,
> +       -1, -1, -1, -1, -1, -1, -1, 31, 26, -1,
> +       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
> +       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
> +       -1, 27, 28, -1, 33};

And even more global tables...

> +
> +enum hdmi_phypwr {
> +       HDMI_PHYPWRCMD_OFF = 0,
> +       HDMI_PHYPWRCMD_LDOON = 1,
> +       HDMI_PHYPWRCMD_TXON = 2
> +};
> +
> +enum hdmi_pll_pwr {
> +       HDMI_PLLPWRCMD_ALLOFF = 0,
> +       HDMI_PLLPWRCMD_PLLONLY = 1,
> +       HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
> +       HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
> +};
> +
> +enum hdmi_core_inputbus_width {
> +       HDMI_INPUT_8BIT = 0,
> +       HDMI_INPUT_10BIT = 1,
> +       HDMI_INPUT_12BIT = 2
> +};
> +
> +enum hdmi_core_dither_trunc {
> +       HDMI_OUTPUTTRUNCATION_8BIT = 0,
> +       HDMI_OUTPUTTRUNCATION_10BIT = 1,
> +       HDMI_OUTPUTTRUNCATION_12BIT = 2,
> +       HDMI_OUTPUTDITHER_8BIT = 3,
> +       HDMI_OUTPUTDITHER_10BIT = 4,
> +       HDMI_OUTPUTDITHER_12BIT = 5
> +};
> +
> +enum hdmi_core_deepcolor_ed {
> +       HDMI_DEEPCOLORPACKECTDISABLE = 0,
> +       HDMI_DEEPCOLORPACKECTENABLE = 1
> +};
> +
> +enum hdmi_core_packet_mode {
> +       HDMI_PACKETMODERESERVEDVALUE = 0,
> +       HDMI_PACKETMODE24BITPERPIXEL = 4,
> +       HDMI_PACKETMODE30BITPERPIXEL = 5,
> +       HDMI_PACKETMODE36BITPERPIXEL = 6,
> +       HDMI_PACKETMODE48BITPERPIXEL = 7
> +};
> +
> +enum hdmi_core_hdmi_dvi {
> +       HDMI_DVI = 0,
> +       HDMI_HDMI = 1
> +};
> +
> +enum hdmi_core_tclkselclkmult {
> +       FPLL05IDCK = 0,
> +       FPLL10IDCK = 1,
> +       FPLL20IDCK = 2,
> +       FPLL40IDCK = 3
> +};
> +
> +enum hdmi_core_fs {
> +       FS_32000 = 0,
> +       FS_44100 = 1
> +};
> +
> +enum hdmi_core_layout {
> +       LAYOUT_2CH = 0,
> +       LAYOUT_8CH = 1
> +};
> +
> +enum hdmi_core_cts_mode {
> +       CTS_MODE_HW = 0,
> +       CTS_MODE_SW = 1
> +};

Enums in C are not inside any namespace. That's why enums need to have
some kind of prefix, just like defines.

 Tomi



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 6/8] OMAP4 : DSS2 : HDMI: HDMI panel driver addition in the DSS
  2011-02-25 14:21 ` [PATCH 6/8] OMAP4 : DSS2 : HDMI: HDMI panel driver addition in the DSS Mythri P K
@ 2011-02-27  9:43   ` Tomi Valkeinen
  2011-02-28  6:14     ` K, Mythri P
  0 siblings, 1 reply; 23+ messages in thread
From: Tomi Valkeinen @ 2011-02-27  9:43 UTC (permalink / raw)
  To: K, Mythri P; +Cc: linux-omap@vger.kernel.org

On Fri, 2011-02-25 at 08:21 -0600, K, Mythri P wrote:
> The panel driver(hdmi_omap4_panel.c) in dss file acts as a controller
> to manage the enable and disable requests and synchronize audio and video.
> Also the header file to export the hdmi registers is added in the
> plat-omap , so that it can be accessed by audio driver.
> 
> Signed-off-by: Mythri P K <mythripk@ti.com>
> ---
>  drivers/video/omap2/dss/Kconfig            |    8 ++
>  drivers/video/omap2/dss/Makefile           |    1 +
>  drivers/video/omap2/dss/hdmi_omap4_panel.c |  190 ++++++++++++++++++++++++++++
>  3 files changed, 199 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/video/omap2/dss/hdmi_omap4_panel.c
> 
> diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
> index fe1ab09..670a55d 100644
> --- a/drivers/video/omap2/dss/Kconfig
> +++ b/drivers/video/omap2/dss/Kconfig
> @@ -125,4 +125,12 @@ config OMAP2_DSS_MIN_FCK_PER_PCK
>  	  Max FCK is 173MHz, so this doesn't work if your PCK
>  	  is very high.
>  
> +config OMAP4_PANEL_HDMI
> +	bool "HDMI panel support"
> +	depends on OMAP2_DSS_HDMI
> +        default n
> +	help
> +	  HDMI panel. This adds the High Definition Multimedia panel.
> +	  See http://www.hdmi.org/ for HDMI specification.
> +
>  endif
> diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
> index 5998b69..95234d4 100644
> --- a/drivers/video/omap2/dss/Makefile
> +++ b/drivers/video/omap2/dss/Makefile
> @@ -6,3 +6,4 @@ omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
>  omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
>  omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
>  omapdss-$(CONFIG_OMAP2_DSS_HDMI) += hdmi.o
> +obj-$(CONFIG_OMAP4_PANEL_HDMI) += hdmi_omap4_panel.o
> diff --git a/drivers/video/omap2/dss/hdmi_omap4_panel.c b/drivers/video/omap2/dss/hdmi_omap4_panel.c
> new file mode 100644
> index 0000000..c28b1f6
> --- /dev/null
> +++ b/drivers/video/omap2/dss/hdmi_omap4_panel.c
> @@ -0,0 +1,190 @@
> +/*
> + * hdmi_omap4_panel.c
> + *
> + * HDMI library support functions for TI OMAP4 processors.
> + *
> + * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
> + * Authors:	MythriPk <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"

This is not used.

> +
> +#include <linux/kernel.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/mutex.h>
> +#include <linux/string.h>
> +#include <linux/delay.h>
> +#include <linux/module.h>
> +#include <linux/seq_file.h>
> +#include <plat/display.h>

Most of these includes are not needed.

> +
> +#include "dss.h"
> +
> +static struct {
> +	struct mutex hdmi_lock;
> +} hdmi;

Static variables in panel drivers are not good, as they won't work if
there are two devices which use the same driver. In this case that
cannot happen, as there's only one HDMI module in DSS. However, it's
worth to mention here in a comment. Or, do it properly and create a per
device data structure.

> +
> +
> +static int hdmi_panel_probe(struct omap_dss_device *dssdev)
> +{
> +	DSSDBG("ENTER hdmi_panel_probe\n");
> +
> +	dssdev->panel.config = OMAP_DSS_LCD_TFT |
> +			OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS;
> +
> +	/*
> +	 * Initialize the timings to 1920 * 1080
> +	 * This is only for framebuffer update not for TV timing setting
> +	 * Setting TV timing will be done only on enable
> +	 */
> +	dssdev->panel.timings.x_res = 1920;
> +	dssdev->panel.timings.y_res = 1080;
> +
> +	DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
> +		dssdev->panel.timings.x_res,
> +		dssdev->panel.timings.y_res);
> +	return 0;
> +}
> +
> +static void hdmi_panel_remove(struct omap_dss_device *dssdev)
> +{
> +
> +}
> +
> +static int hdmi_panel_enable(struct omap_dss_device *dssdev)
> +{
> +	int r = 0;
> +	DSSDBG("ENTER hdmi_panel_enable\n");
> +
> +	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)
> +		return -EINVAL;
> +
> +	mutex_lock(&hdmi.hdmi_lock);

I commented about this in earlier mails already. You need to use the
locks consistently and have the dssdev->state reads also inside the
lock.

Think what happens if, say, two threads call hdmi_panel_enable at the
same time.

 Tomi



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 5/8] OMAP4 : DSS2 : HDMI: HDMI driver addition in the DSS drivers interface
  2011-02-25 14:21 ` [PATCH 5/8] OMAP4 : DSS2 : HDMI: HDMI driver addition in the DSS drivers interface Mythri P K
@ 2011-02-27 10:17   ` Tomi Valkeinen
  2011-02-28  6:11     ` K, Mythri P
  0 siblings, 1 reply; 23+ messages in thread
From: Tomi Valkeinen @ 2011-02-27 10:17 UTC (permalink / raw)
  To: K, Mythri P; +Cc: linux-omap@vger.kernel.org

On Fri, 2011-02-25 at 08:21 -0600, K, Mythri P wrote:
> Adding the hdmi interface driver(hdmi.c) to the dss driver.
> It configures the audio and video portion of HDMI in the
> display header file to be accessed by the panels.
> 
> Signed-off-by: Mythri P K <mythripk@ti.com>
> ---
>  drivers/video/omap2/dss/Kconfig   |    8 +
>  drivers/video/omap2/dss/Makefile  |    1 +
>  drivers/video/omap2/dss/display.c |    3 +
>  drivers/video/omap2/dss/dss.h     |   33 +
>  drivers/video/omap2/dss/hdmi.c    | 1276 +++++++++++++++++++++++++++++++++++++
>  drivers/video/omap2/dss/hdmi.h    |    9 +
>  6 files changed, 1330 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/video/omap2/dss/hdmi.c
> 
> diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
> index 0d031b2..fe1ab09 100644
> --- a/drivers/video/omap2/dss/Kconfig
> +++ b/drivers/video/omap2/dss/Kconfig
> @@ -60,6 +60,14 @@ config OMAP2_DSS_VENC
>         help
>           OMAP Video Encoder support for S-Video and composite TV-out.
> 
> +config OMAP2_DSS_HDMI
> +       bool "HDMI support"
> +       depends on ARCH_OMAP4
> +        default n
> +       help
> +         HDMI Interface. This adds the High Definition Multimedia Interface.
> +         See http://www.hdmi.org/ for HDMI specification.
> +
>  config OMAP2_DSS_SDI
>         bool "SDI support"
>         depends on ARCH_OMAP3
> diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
> index 7db17b5..5998b69 100644
> --- a/drivers/video/omap2/dss/Makefile
> +++ b/drivers/video/omap2/dss/Makefile
> @@ -5,3 +5,4 @@ omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
>  omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
>  omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
>  omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
> +omapdss-$(CONFIG_OMAP2_DSS_HDMI) += hdmi.o
> diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
> index e10b303..cbab61a 100644
> --- a/drivers/video/omap2/dss/display.c
> +++ b/drivers/video/omap2/dss/display.c
> @@ -447,6 +447,9 @@ void dss_init_device(struct platform_device *pdev,
>                 r = dsi_init_display(dssdev);
>                 break;
>  #endif
> +       case OMAP_DISPLAY_TYPE_HDMI:
> +               r = hdmi_init_display(dssdev);
> +               break;
>         default:
>                 BUG();
>         }
> diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
> index d199ba7..171877e 100644
> --- a/drivers/video/omap2/dss/dss.h
> +++ b/drivers/video/omap2/dss/dss.h
> @@ -163,6 +163,16 @@ struct dsi_clock_info {
>         bool use_dss2_fck;
>  };
> 
> +/* HDMI PLL structure */
> +struct hdmi_pll_info {
> +       u16 regn;
> +       u16 regm;
> +       u32 regmf;
> +       u16 regm2;
> +       u16 regsd;
> +       u16 dcofreq;
> +};
> +
>  struct seq_file;
>  struct platform_device;
> 
> @@ -428,6 +438,29 @@ static inline void venc_uninit_platform_driver(void)
>  }
>  #endif
> 
> +/* HDMI */
> +#ifdef CONFIG_OMAP2_DSS_HDMI
> +int hdmi_init_platform_driver(void);
> +void hdmi_uninit_platform_driver(void);
> +int hdmi_init_display(struct omap_dss_device *dssdev);
> +#else
> +static inline int hdmi_init_display(struct omap_dss_device *dssdev)
> +{
> +       return 0;
> +}
> +static inline int hdmi_init_platform_driver(void)
> +{
> +       return 0;
> +}
> +static inline void hdmi_uninit_platform_driver(void)
> +{
> +}
> +#endif
> +int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
> +void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
> +int omapdss_hdmi_display_suspend(struct omap_dss_device *dssdev);
> +int omapdss_hdmi_display_resume(struct omap_dss_device *dssdev);
> +
>  /* RFBI */
>  #ifdef CONFIG_OMAP2_DSS_RFBI
>  int rfbi_init_platform_driver(void);
> diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
> new file mode 100644
> index 0000000..1cd861f
> --- /dev/null
> +++ b/drivers/video/omap2/dss/hdmi.c
> @@ -0,0 +1,1276 @@
> +/*
> + * 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

Who is Yong Zhi and where's his signed-off-by?

> + *     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 <plat/display.h>
> +
> +#include "dss.h"
> +#include "hdmi.h"
> +
> +static struct {
> +       struct mutex lock;
> +       struct omap_display_platform_data *pdata;
> +       struct platform_device *pdev;
> +       void __iomem *base_wp;  /* HDMI wrapper */
> +       int code;
> +       int mode;
> +       struct hdmi_config cfg;
> +} hdmi;
> +
> +static inline void hdmi_write_reg(const struct hdmi_reg idx, u32 val)
> +{
> +       __raw_writel(val, hdmi.base_wp + idx.idx);
> +}
> +
> +static inline u32 hdmi_read_reg(const struct hdmi_reg idx)
> +{
> +       u32 l;
> +       l = __raw_readl(hdmi.base_wp + idx.idx);
> +       return l;
> +}

No need for the l variable.

> +
> +static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx,
> +                               int b2, int b1, u32 val)
> +{
> +       u32 t = 0;
> +       while (val != FLD_GET(hdmi_read_reg(idx), b2, b1)) {

There's REG_GET macro used in other DSS files to read bits from the
registers.

> +               udelay(1);
> +               if (t++ > 10000)
> +                       return !val;
> +       }
> +       return val;
> +}
> +
> +int hdmi_init_display(struct omap_dss_device *dssdev)
> +{
> +       DSSDBG("init_display\n");
> +
> +       return 0;
> +}
> +
> +static int hdmi_pll_init(int refsel, int dcofreq,
> +               struct hdmi_pll_info *fmt, u16 sd)
> +{
> +       u32 r;
> +
> +       /* PLL start always use manual mode */
> +       REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
> +
> +       r = hdmi_read_reg(PLLCTRL_CFG1);
> +       r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
> +       r = FLD_MOD(r, fmt->regn, 8, 1);  /* CFG1_PLL_REGN */
> +
> +       hdmi_write_reg(PLLCTRL_CFG1, r);
> +
> +       r = hdmi_read_reg(PLLCTRL_CFG2);
> +
> +       r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
> +       r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
> +       r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
> +
> +       if (dcofreq) {
> +               /* divider programming for frequency beyond 1000Mhz */
> +               REG_FLD_MOD(PLLCTRL_CFG3, sd, 17, 10);
> +               r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
> +       } else {
> +               r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
> +       }
> +
> +       hdmi_write_reg(PLLCTRL_CFG2, r);
> +
> +       r = hdmi_read_reg(PLLCTRL_CFG4);
> +       r = FLD_MOD(r, fmt->regm2, 24, 18);
> +       r = FLD_MOD(r, fmt->regmf, 17, 0);
> +
> +       hdmi_write_reg(PLLCTRL_CFG4, r);
> +
> +       /* go now */
> +       REG_FLD_MOD(PLLCTRL_PLL_GO, 0x1, 0, 0);
> +
> +       /* wait for bit change */
> +       if (hdmi_wait_for_bit_change(PLLCTRL_PLL_GO, 0, 0, 1) != 1) {
> +               DSSERR("PLL GO bit not set\n");
> +               return -ETIMEDOUT;
> +       }
> +
> +       /* Wait till the lock bit is set in PLL status */
> +       if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
> +               DSSWARN("cannot lock PLL\n");
> +               DSSWARN("CFG1 0x%x\n",
> +                       hdmi_read_reg(PLLCTRL_CFG1));
> +               DSSWARN("CFG2 0x%x\n",
> +                       hdmi_read_reg(PLLCTRL_CFG2));
> +               DSSWARN("CFG4 0x%x\n",
> +                       hdmi_read_reg(PLLCTRL_CFG4));
> +               return -ETIMEDOUT;
> +       }
> +
> +       DSSDBG("PLL locked!\n");
> +
> +       return 0;
> +}
> +
> +static int hdmi_pll_reset(void)
> +{
> +       /* SYSRESET  controlled by power FSM */
> +       REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 3, 3);
> +
> +       /* READ 0x0 reset is in progress */
> +       if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) {
> +               DSSERR("Failed to sysreset PLL\n");
> +               return -ETIMEDOUT;
> +       }
> +
> +       return 0;
> +}
> +
> +static int hdmi_phy_init(void)
> +{
> +       u16 r = 0;
> +
> +       /*
> +        * wait till PHY_PWR_STATUS=LDOON
> +        * HDMI_PHYPWRCMD_LDOON = 1
> +        */
> +       r = hdmi_wait_phy_pwr(1);

Why doesn't hdmi_wait_phy_pwr use an enum?

> +       if (r)
> +               return r;
> +
> +       /* wait till PHY_PWR_STATUS=TXON */
> +       r = hdmi_wait_phy_pwr(2);
> +       if (r)
> +               return r;
> +
> +       /*
> +        * Read address 0 in order to get the SCP reset done completed
> +        * Dummy access performed to make sure reset is done
> +        */
> +       hdmi_read_reg(HDMI_TXPHY_TX_CTRL);
> +
> +       /*
> +        * Write to phy address 0 to configure the clock
> +        * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field
> +        */
> +       REG_FLD_MOD(HDMI_TXPHY_TX_CTRL, 0x1, 31, 30);
> +
> +       /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */
> +       hdmi_write_reg(HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
> +
> +       /* Setup max LDO voltage */
> +       REG_FLD_MOD(HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
> +
> +       /* Write to phy address 3 to change the polarity control */
> +       REG_FLD_MOD(HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
> +
> +       return 0;
> +}
> +
> +int hdmi_pll_program(struct hdmi_pll_info *fmt)

This, and some other functions in this file, could be static.

> +{
> +       u16 r = 0;
> +       int refsel;
> +
> +       /* wait for wrapper reset */
> +       hdmi_wait_softreset();
> +
> +       /* power off PLL */
> +       r = hdmi_wait_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
> +       if (r)
> +               return r;
> +
> +       /* power on PLL */
> +       r = hdmi_wait_pll_pwr(HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
> +       if (r)
> +               return r;
> +
> +       hdmi_pll_reset();
> +
> +       refsel = 0x3; /* select SYSCLK reference */
> +
> +       r = hdmi_pll_init(refsel, fmt->dcofreq, fmt, fmt->regsd);
> +       if (r)
> +               return r;
> +
> +       return 0;
> +}
> +
> +static void hdmi_phy_off(void)
> +{
> +       /*
> +        * Wait till PHY_PWR_STATUS=OFF
> +        * HDMI_PHYPWRCMD_OFF = 0
> +        */
> +       hdmi_wait_phy_pwr(0);
> +}
> +
> +int hdmi_core_ddc_edid(u8 *pEDID, int ext)
> +{
> +       u32 i, j, l;
> +       char checksum = 0;
> +       u32 offset = 0;
> +
> +       /* Turn on CLK for DDC */
> +       REG_FLD_MOD(HDMI_CORE_AV_DPD, 0x7, 2, 0);
> +
> +       /* HACK : DDC needs time to stablize */
> +       mdelay(10);

So what is the reason for this? It's a sleep that for unknown reason
make the code work? Or is there an idea why this is needed?

> +
> +       if (!ext) {
> +               /* Clk SCL Devices */
> +               REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0xA, 3, 0);
> +
> +               /* HDMI_CORE_DDC_STATUS_IN_PROG No timer needed */
> +               if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
> +                                               4, 4, 0) != 0) {
> +                       DSSERR("Failed to program DDC\n");
> +                       return -ETIMEDOUT;
> +               }
> +
> +               /* Clear FIFO */
> +               REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x9, 3, 0);
> +
> +               /* HDMI_CORE_DDC_STATUS_IN_PROG */
> +               if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
> +                                               4, 4, 0) != 0) {
> +                       DSSERR("Failed to program DDC\n");
> +                       return -ETIMEDOUT;
> +               }
> +
> +       } else {
> +               if (ext % 2 != 0)
> +                       offset = 0x80;
> +       }
> +
> +       /* Load Segment Address Register */
> +       REG_FLD_MOD(HDMI_CORE_DDC_SEGM, ext/2, 7, 0);
> +
> +       /* Load Slave Address Register */
> +       REG_FLD_MOD(HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
> +
> +       /* Load Offset Address Register */
> +       REG_FLD_MOD(HDMI_CORE_DDC_OFFSET, offset, 7, 0);
> +
> +       /* Load Byte Count */
> +       REG_FLD_MOD(HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
> +       REG_FLD_MOD(HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
> +
> +       /* Set DDC_CMD */
> +       if (ext)
> +               REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x4, 3, 0);
> +       else
> +               REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x2, 3, 0);
> +
> +       /*
> +        * Do not optimize this part of the code, seems
> +        * DDC bus needs some time to get stabilized
> +        */
> +       l = hdmi_read_reg(HDMI_CORE_DDC_STATUS);
> +
> +       /* HDMI_CORE_DDC_STATUS_BUS_LOW */
> +       if (FLD_GET(l, 6, 6) == 1) {
> +               DSSWARN("I2C Bus Low?\n");
> +               return -EIO;
> +       }
> +       /* HDMI_CORE_DDC_STATUS_NO_ACK */
> +       if (FLD_GET(l, 5, 5) == 1) {
> +               DSSWARN("I2C No Ack\n");
> +               return -EIO;
> +       }
> +
> +       i = ext * 128;
> +       j = 0;
> +       while (((FLD_GET(hdmi_read_reg(HDMI_CORE_DDC_STATUS), 4, 4) == 1) ||
> +               (FLD_GET(hdmi_read_reg(HDMI_CORE_DDC_STATUS), 2, 2) == 0)) &&
> +                                                               j < 128) {
> +               if (FLD_GET(hdmi_read_reg(HDMI_CORE_DDC_STATUS), 2, 2) == 0) {
> +                       /* FIFO not empty */
> +                       pEDID[i++] = FLD_GET(
> +                               hdmi_read_reg(HDMI_CORE_DDC_DATA), 7, 0);
> +                       j++;
> +               }
> +       }
> +
> +       for (j = 0; j < 128; j++)
> +               checksum += pEDID[j];
> +
> +       if (checksum != 0) {
> +               DSSERR("E-EDID checksum failed!!\n");
> +               return -EIO;
> +       }
> +
> +       return 0;
> +}
> +
> +int read_edid(u8 *pEDID, u16 max_length)
> +{
> +       int r = 0, n = 0, i = 0;
> +       int max_ext_blocks = (max_length / 128) - 1;
> +
> +       r = hdmi_core_ddc_edid(pEDID, 0);
> +       if (r) {
> +               return -EIO;
> +       } else {
> +               n = pEDID[0x7e];
> +
> +               /*
> +                * README: need to comply with max_length set by the caller.
> +                * Better implementation should be to allocate necessary
> +                * memory to store EDID according to nb_block field found
> +                * in first block
> +                */
> +
> +               if (n > max_ext_blocks)
> +                       n = max_ext_blocks;
> +
> +               for (i = 1; i <= n; i++) {
> +                       r = hdmi_core_ddc_edid(pEDID, i);
> +                       if (r)
> +                               return -EIO;
> +               }
> +       }
> +       return 0;
> +}
> +
> +static inline void print_omap_video_timings(struct omap_video_timings *timings)

Why is this inline?

> +{
> +       DSSINFO("Timing Info:\n");
> +       DSSINFO("pixel_clk = %d\n", timings->pixel_clock);
> +       DSSINFO("  x_res     = %d\n", timings->x_res);
> +       DSSINFO("  y_res     = %d\n", timings->y_res);
> +       DSSINFO("  hfp       = %d\n", timings->hfp);
> +       DSSINFO("  hsw       = %d\n", timings->hsw);
> +       DSSINFO("  hbp       = %d\n", timings->hbp);
> +       DSSINFO("  vfp       = %d\n", timings->vfp);
> +       DSSINFO("  vsw       = %d\n", timings->vsw);
> +       DSSINFO("  vbp       = %d\n", timings->vbp);
> +}
> +
> +static int get_timings_index(void)
> +{
> +       int code;
> +
> +       if (hdmi.mode == 0)
> +               code = code_vesa[hdmi.code];
> +       else
> +               code = code_cea[hdmi.code];
> +
> +       if (code == -1) {
> +               code = 9;
> +               /* HDMI code 16 corresponds to 1920 * 1080 */
> +               hdmi.code = 16;
> +               /* HDMI mode 1 corresponds to HDMI 0 to DVI */
> +               hdmi.mode = HDMI_HDMI;
> +       }
> +       return code;
> +}
> +
> +static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
> +{
> +       int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0;
> +       int timing_vsync = 0, timing_hsync = 0;
> +       struct omap_video_timings temp;
> +       struct hdmi_cm cm = {-1};
> +       DSSDBG("hdmi_get_code\n");
> +
> +       for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) {
> +               temp = cea_vesa_timings[i].timings;
> +               if ((temp.pixel_clock == timing->pixel_clock) &&
> +                       (temp.x_res == timing->x_res) &&
> +                       (temp.y_res == timing->y_res)) {
> +
> +                       temp_hsync = temp.hfp + temp.hsw + temp.hbp;
> +                       timing_hsync = timing->hfp + timing->hsw + timing->hbp;
> +                       temp_vsync = temp.vfp + temp.vsw + temp.vbp;
> +                       timing_vsync = timing->vfp + timing->vsw + timing->vbp;
> +
> +                       DSSDBG("temp_hsync = %d , temp_vsync = %d"
> +                               "timing_hsync = %d, timing_vsync = %d\n",
> +                               temp_hsync, temp_hsync,
> +                               timing_hsync, timing_vsync);
> +
> +                       if ((temp_hsync == timing_hsync) &&
> +                                       (temp_vsync == timing_vsync)) {
> +                               code = i;
> +                               cm.code = code_index[i];
> +                               if (code < 14)
> +                                       cm.mode = HDMI_HDMI;
> +                               else
> +                                       cm.mode = HDMI_DVI;
> +                               DSSINFO("Hdmi_code = %d mode = %d\n",
> +                                        cm.code, cm.mode);
> +                               print_omap_video_timings(&temp);
> +                               break;
> +                        }
> +               }
> +       }
> +
> +       return cm;
> +}
> +
> +void get_horz_vert_timing_info(int current_descriptor_addrs, u8 *edid ,
> +               struct omap_video_timings *timings)
> +{
> +       /* X and Y resolution */
> +       timings->x_res = (((edid[current_descriptor_addrs + 4] & 0xF0) << 4) |
> +                        edid[current_descriptor_addrs + 2]);
> +       timings->y_res = (((edid[current_descriptor_addrs + 7] & 0xF0) << 4) |
> +                        edid[current_descriptor_addrs + 5]);
> +
> +       timings->pixel_clock = ((edid[current_descriptor_addrs + 1] << 8) |
> +                               edid[current_descriptor_addrs]);
> +
> +       timings->pixel_clock = 10 * timings->pixel_clock;
> +
> +       /* HORIZONTAL FRONT PORCH */
> +       timings->hfp = edid[current_descriptor_addrs + 8] |
> +                       ((edid[current_descriptor_addrs + 11] & 0xc0) << 2);
> +       /* HORIZONTAL SYNC WIDTH */
> +       timings->hsw = edid[current_descriptor_addrs + 9] |
> +                       ((edid[current_descriptor_addrs + 11] & 0x30) << 4);
> +       /* HORIZONTAL BACK PORCH */
> +       timings->hbp = (((edid[current_descriptor_addrs + 4] & 0x0F) << 8) |
> +                       edid[current_descriptor_addrs + 3]) -
> +                       (timings->hfp + timings->hsw);
> +       /* VERTICAL FRONT PORCH */
> +       timings->vfp = ((edid[current_descriptor_addrs + 10] & 0xF0) >> 4) |
> +                       ((edid[current_descriptor_addrs + 11] & 0x0f) << 2);
> +       /* VERTICAL SYNC WIDTH */
> +       timings->vsw = (edid[current_descriptor_addrs + 10] & 0x0F) |
> +                       ((edid[current_descriptor_addrs + 11] & 0x03) << 4);
> +       /* VERTICAL BACK PORCH */
> +       timings->vbp = (((edid[current_descriptor_addrs + 7] & 0x0F) << 8) |
> +                       edid[current_descriptor_addrs + 6]) -
> +                       (timings->vfp + timings->vsw);
> +
> +       print_omap_video_timings(timings);
> +
> +}
> +
> +/* Description : This function gets the resolution information from EDID */
> +static void get_edid_timing_data(u8 *edid)
> +{
> +       u8 count, code;
> +       u16 current_descriptor_addrs;
> +       struct hdmi_cm cm;
> +
> +       /* seach block 0, there are 4 DTDs arranged in priority order */
> +       for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) {
> +               current_descriptor_addrs =
> +                       EDID_DESCRIPTOR_BLOCK0_ADDRESS +
> +                       count * EDID_TIMING_DESCRIPTOR_SIZE;
> +               get_horz_vert_timing_info(current_descriptor_addrs,
> +                               edid, &edid_timings);
> +               cm = hdmi_get_code(&edid_timings);
> +               DSSINFO("Block0[%d] value matches code = %d , mode = %d\n",
> +                       count, cm.code, cm.mode);
> +               if (cm.code == -1) {
> +                       continue;
> +               } else {
> +                       hdmi.code = cm.code;
> +                       hdmi.mode = cm.mode;
> +                       DSSINFO("code = %d , mode = %d\n",
> +                               hdmi.code, hdmi.mode);
> +                       return;
> +               }
> +       }
> +       if (edid[0x7e] != 0x00) {
> +               for (count = 0; count < EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR;
> +                       count++) {
> +                       current_descriptor_addrs =
> +                       EDID_DESCRIPTOR_BLOCK1_ADDRESS +
> +                       count * EDID_TIMING_DESCRIPTOR_SIZE;
> +                       get_horz_vert_timing_info(current_descriptor_addrs,
> +                                               edid, &edid_timings);
> +                       cm = hdmi_get_code(&edid_timings);
> +                       DSSINFO("Block1[%d] value matches code = %d, mode = %d",
> +                               count, cm.code, cm.mode);
> +                       if (cm.code == -1) {
> +                               continue;
> +                       } else {
> +                               hdmi.code = cm.code;
> +                               hdmi.mode = cm.mode;
> +                               DSSINFO("code = %d , mode = %d\n",
> +                                       hdmi.code, hdmi.mode);
> +                               return;
> +                       }
> +               }
> +       }
> +
> +       DSSINFO("no valid timing found , falling back to VGA\n");
> +       hdmi.code = 4; /* setting default value of 640 480 VGA */
> +       hdmi.mode = HDMI_DVI;
> +       code = code_vesa[hdmi.code];
> +       edid_timings = cea_vesa_timings[code].timings;
> +}
> +
> +static int hdmi_read_edid(struct omap_video_timings *dp)
> +{
> +       int ret = 0, code;
> +
> +       memset(edid, 0, HDMI_EDID_MAX_LENGTH);
> +
> +       if (!edid_set)
> +               ret = read_edid(edid, HDMI_EDID_MAX_LENGTH);
> +
> +       if (ret != 0) {
> +               DSSWARN("failed to read E-EDID\n");
> +       } else {
> +               if (!memcmp(edid, header, sizeof(header))) {
> +                       /* search for timings of default resolution */
> +                       get_edid_timing_data(edid);
> +                       edid_set = true;
> +               }
> +       }
> +
> +       if (!edid_set) {
> +               DSSINFO("fallback to VGA\n");
> +               hdmi.code = 4; /* setting default value of 640 480 VGA */
> +               hdmi.mode = HDMI_DVI;
> +       }
> +
> +       code = get_timings_index();
> +
> +       *dp = cea_vesa_timings[code].timings;
> +
> +       DSSDBG("print EDID timings\n");
> +       print_omap_video_timings(dp);
> +
> +       return 0;
> +}
> +
> +static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
> +                       struct hdmi_core_infoframe_avi *avi_cfg,
> +                       struct hdmi_core_packet_enable_repeat *repeat_cfg)
> +{
> +       DSSDBG("Enter hdmi_core_init\n");
> +
> +       /* video core */
> +       video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
> +       video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT;
> +       video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE;
> +       video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
> +       video_cfg->hdmi_dvi = HDMI_DVI;
> +       video_cfg->tclk_sel_clkmult = FPLL10IDCK;
> +
> +       /* info frame */
> +       avi_cfg->db1_format = 0;
> +       avi_cfg->db1_active_info = 0;
> +       avi_cfg->db1_bar_info_dv = 0;
> +       avi_cfg->db1_scan_info = 0;
> +       avi_cfg->db2_colorimetry = 0;
> +       avi_cfg->db2_aspect_ratio = 0;
> +       avi_cfg->db2_active_fmt_ar = 0;
> +       avi_cfg->db3_itc = 0;
> +       avi_cfg->db3_ec = 0;
> +       avi_cfg->db3_q_range = 0;
> +       avi_cfg->db3_nup_scaling = 0;
> +       avi_cfg->db4_videocode = 0;
> +       avi_cfg->db5_pixel_repeat = 0;
> +       avi_cfg->db6_7_line_eoftop = 0 ;
> +       avi_cfg->db8_9_line_sofbottom = 0;
> +       avi_cfg->db10_11_pixel_eofleft = 0;
> +       avi_cfg->db12_13_pixel_sofright = 0;
> +
> +       /* packet enable and repeat */
> +       repeat_cfg->audio_pkt = 0;
> +       repeat_cfg->audio_pkt_repeat = 0;
> +       repeat_cfg->avi_infoframe = 0;
> +       repeat_cfg->avi_infoframe_repeat = 0;
> +       repeat_cfg->gen_cntrl_pkt = 0;
> +       repeat_cfg->gen_cntrl_pkt_repeat = 0;
> +       repeat_cfg->generic_pkt = 0;
> +       repeat_cfg->generic_pkt_repeat = 0;
> +}
> +
> +static void hdmi_core_powerdown_disable(void)
> +{
> +       DSSDBG("Enter hdmi_core_powerdown_disable\n");
> +       REG_FLD_MOD(HDMI_CORE_CTRL1, 0x0, 0, 0);
> +}
> +
> +static void hdmi_core_swreset_release(void)
> +{
> +       DSSDBG("Enter hdmi_core_swreset_release\n");
> +       REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x0, 0, 0);
> +}
> +
> +static void hdmi_core_swreset_assert(void)
> +{
> +       DSSDBG("Enter hdmi_core_swreset_assert\n");
> +       REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x1, 0, 0);
> +}
> +
> +/* DSS_HDMI_CORE_VIDEO_CONFIG */
> +static void hdmi_core_video_config(struct hdmi_core_video_config *cfg)
> +{
> +       u32 r = 0;
> +
> +       /* sys_ctrl1 default configuration not tunable */
> +       r = hdmi_read_reg(HDMI_CORE_CTRL1);
> +       r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5);
> +       r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4);
> +       r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2);
> +       r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1);
> +       hdmi_write_reg(HDMI_CORE_CTRL1, r);
> +
> +       REG_FLD_MOD(HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
> +
> +       /* Vid_Mode */
> +       r = hdmi_read_reg(HDMI_CORE_SYS_VID_MODE);
> +
> +       /* dither truncation configuration */
> +       if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) {
> +               r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6);
> +               r = FLD_MOD(r, 1, 5, 5);
> +       } else {
> +               r = FLD_MOD(r, cfg->op_dither_truc, 7, 6);
> +               r = FLD_MOD(r, 0, 5, 5);
> +       }
> +       hdmi_write_reg(HDMI_CORE_SYS_VID_MODE, r);
> +
> +       /* HDMI_Ctrl */
> +       r = hdmi_read_reg(HDMI_CORE_AV_HDMI_CTRL);
> +       r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);
> +       r = FLD_MOD(r, cfg->pkt_mode, 5, 3);
> +       r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0);
> +       hdmi_write_reg(HDMI_CORE_AV_HDMI_CTRL, r);
> +
> +       /* TMDS_CTRL */
> +       REG_FLD_MOD(HDMI_CORE_SYS_TMDS_CTRL,
> +               cfg->tclk_sel_clkmult, 6, 5);
> +}
> +
> +static void hdmi_core_aux_infoframe_avi_config(
> +               struct hdmi_core_infoframe_avi info_avi)
> +{
> +       u32 val;
> +       char sum = 0, checksum = 0;
> +
> +       sum += 0x82 + 0x002 + 0x00D;
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_TYPE, 0x082);
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_VERS, 0x002);
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_LEN, 0x00D);
> +
> +       val = (info_avi.db1_format << 5) |
> +               (info_avi.db1_active_info << 4) |
> +               (info_avi.db1_bar_info_dv << 2) |
> +               (info_avi.db1_scan_info);
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(0), val);
> +       sum += val;
> +
> +       val = (info_avi.db2_colorimetry << 6) |
> +               (info_avi.db2_aspect_ratio << 4) |
> +               (info_avi.db2_active_fmt_ar);
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(1), val);
> +       sum += val;
> +
> +       val = (info_avi.db3_itc << 7) |
> +               (info_avi.db3_ec << 4) |
> +               (info_avi.db3_q_range << 2) |
> +               (info_avi.db3_nup_scaling);
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(2), val);
> +       sum += val;
> +
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(3), info_avi.db4_videocode);
> +       sum += info_avi.db4_videocode;
> +
> +       val = info_avi.db5_pixel_repeat;
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(4), val);
> +       sum += val;
> +
> +       val = info_avi.db6_7_line_eoftop & 0x00FF;
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(5), val);
> +       sum += val;
> +
> +       val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(6), val);
> +       sum += val;
> +
> +       val = info_avi.db8_9_line_sofbottom & 0x00FF;
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(7), val);
> +       sum += val;
> +
> +       val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(8), val);
> +       sum += val;
> +
> +       val = info_avi.db10_11_pixel_eofleft & 0x00FF;
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(9), val);
> +       sum += val;
> +
> +       val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(10), val);
> +       sum += val;
> +
> +       val = info_avi.db12_13_pixel_sofright & 0x00FF;
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(11), val);
> +       sum += val;
> +
> +       val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(12), val);
> +       sum += val;
> +
> +       checksum = 0x100 - sum;
> +       hdmi_write_reg(HDMI_CORE_AV_AVI_CHSUM, checksum);
> +}
> +
> +static void hdmi_core_av_packet_config(
> +               struct hdmi_core_packet_enable_repeat repeat_cfg)
> +{
> +       /* enable/repeat the infoframe */
> +       hdmi_write_reg(HDMI_CORE_AV_PB_CTRL1,
> +               (repeat_cfg.audio_pkt << 5)|
> +               (repeat_cfg.audio_pkt_repeat << 4)|
> +               (repeat_cfg.avi_infoframe << 1)|
> +               (repeat_cfg.avi_infoframe_repeat));
> +
> +       /* enable/repeat the packet */
> +       hdmi_write_reg(HDMI_CORE_AV_PB_CTRL2,
> +               (repeat_cfg.gen_cntrl_pkt << 3)|
> +               (repeat_cfg.gen_cntrl_pkt_repeat << 2)|
> +               (repeat_cfg.generic_pkt << 1)|
> +               (repeat_cfg.generic_pkt_repeat));
> +}
> +
> +static void hdmi_wp_init(struct hdmi_video_timing *timings,
> +                       struct hdmi_video_format *video_fmt,
> +                       struct hdmi_video_interface *video_int)
> +{
> +       DSSDBG("Enter hdmi_wp_init\n");
> +
> +       timings->hbp = 0;
> +       timings->hfp = 0;
> +       timings->hsw = 0;
> +       timings->vbp = 0;
> +       timings->vfp = 0;
> +       timings->vsw = 0;
> +
> +       video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
> +       video_fmt->y_res = 0;
> +       video_fmt->x_res = 0;
> +
> +       video_int->vsp = 0;
> +       video_int->hsp = 0;
> +
> +       video_int->interlacing = 0;
> +       video_int->tm = 0; /* HDMI_TIMING_SLAVE */
> +
> +}
> +
> +/* PHY_PWR_CMD */
> +int hdmi_wait_phy_pwr(int val)
> +{
> +       REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 7, 6);
> +
> +       if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 5, 4, val) != val) {
> +               DSSERR("Failed to set PHY power mode to %d\n", val);
> +               return -ENODEV;
> +       }
> +
> +       return 0;
> +}
> +
> +/* PLL_PWR_CMD */
> +int hdmi_wait_pll_pwr(int val)
> +{
> +       REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 3, 2);
> +
> +       /* wait till PHY_PWR_STATUS=ON */
> +       if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 1, 0, val) != val) {
> +               DSSERR("Failed to set PHY_PWR_STATUS to ON\n");
> +               return -ENODEV;
> +       }
> +
> +       return 0;
> +}
> +
> +void hdmi_wp_video_stop(void)
> +{
> +       REG_FLD_MOD(HDMI_WP_VIDEO_CFG, 0, 31, 31);
> +}
> +
> +void hdmi_wp_video_start(void)
> +{
> +       REG_FLD_MOD(HDMI_WP_VIDEO_CFG, (u32)0x1, 31, 31);
> +}
> +
> +static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
> +       struct hdmi_video_timing *timings, struct hdmi_config *param)
> +{
> +       DSSDBG("Enter hdmi_wp_video_init_format\n");
> +
> +       video_fmt->y_res = param->lpp;
> +       video_fmt->x_res = param->ppl;
> +
> +       timings->hbp = param->hbp;
> +       timings->hfp = param->hfp;
> +       timings->hsw = param->hsw;
> +       timings->vbp = param->vbp;
> +       timings->vfp = param->vfp;
> +       timings->vsw = param->vsw;
> +}
> +
> +static void hdmi_wp_video_config_format(
> +               struct hdmi_video_format *video_fmt)
> +{
> +       u32 l = 0;
> +
> +       REG_FLD_MOD(HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, 10, 8);
> +
> +       l |= FLD_VAL(video_fmt->y_res, 31, 16);
> +       l |= FLD_VAL(video_fmt->x_res, 15, 0);
> +       hdmi_write_reg(HDMI_WP_VIDEO_SIZE, l);
> +}
> +
> +static void hdmi_wp_video_config_interface(
> +               struct hdmi_video_interface *video_int)
> +{
> +       u32 r;
> +       DSSDBG("Enter hdmi_wp_video_config_interface\n");
> +
> +       r = hdmi_read_reg(HDMI_WP_VIDEO_CFG);
> +       r = FLD_MOD(r, video_int->vsp, 7, 7);
> +       r = FLD_MOD(r, video_int->hsp, 6, 6);
> +       r = FLD_MOD(r, video_int->interlacing, 3, 3);
> +       r = FLD_MOD(r, video_int->tm, 1, 0);
> +       hdmi_write_reg(HDMI_WP_VIDEO_CFG, r);
> +}
> +
> +static void hdmi_wp_video_config_timing(
> +               struct hdmi_video_timing *timings)
> +{
> +       u32 timing_h = 0;
> +       u32 timing_v = 0;
> +
> +       DSSDBG("Enter hdmi_wp_video_config_timing\n");
> +
> +       timing_h |= FLD_VAL(timings->hbp, 31, 20);
> +       timing_h |= FLD_VAL(timings->hfp, 19, 8);
> +       timing_h |= FLD_VAL(timings->hsw, 7, 0);
> +       hdmi_write_reg(HDMI_WP_VIDEO_TIMING_H, timing_h);
> +
> +       timing_v |= FLD_VAL(timings->vbp, 31, 20);
> +       timing_v |= FLD_VAL(timings->vfp, 19, 8);
> +       timing_v |= FLD_VAL(timings->vsw, 7, 0);
> +       hdmi_write_reg(HDMI_WP_VIDEO_TIMING_V, timing_v);
> +}
> +
> +void hdmi_lib_enable(struct hdmi_config *cfg)
> +{

There is no library here.

> +       /* HDMI */
> +       struct hdmi_video_timing video_timing;
> +       struct hdmi_video_format video_format;
> +       struct hdmi_video_interface video_interface;
> +       /* HDMI core */
> +       struct hdmi_core_infoframe_avi avi_cfg;
> +       struct hdmi_core_video_config v_core_cfg;
> +       struct hdmi_core_packet_enable_repeat repeat_cfg;
> +
> +       hdmi_wp_init(&video_timing, &video_format,
> +               &video_interface);
> +
> +       hdmi_core_init(&v_core_cfg,
> +               &avi_cfg,
> +               &repeat_cfg);
> +
> +       /* init DSS register */
> +       hdmi_wp_video_init_format(&video_format,
> +                       &video_timing, cfg);
> +
> +       hdmi_wp_video_config_timing(&video_timing);
> +
> +       /* video config */
> +       video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422;
> +
> +       hdmi_wp_video_config_format(&video_format);
> +
> +       video_interface.vsp = cfg->v_pol;
> +       video_interface.hsp = cfg->h_pol;
> +       video_interface.interlacing = cfg->interlace;
> +       video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
> +
> +       hdmi_wp_video_config_interface(&video_interface);
> +
> +       /*
> +        * configure core video part
> +        * set software reset in the core
> +        */
> +       hdmi_core_swreset_assert();
> +
> +       /* power down off */
> +       hdmi_core_powerdown_disable();
> +
> +       v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
> +       v_core_cfg.hdmi_dvi = cfg->hdmi_dvi;
> +
> +       hdmi_core_video_config(&v_core_cfg);
> +
> +       /* release software reset in the core */
> +       hdmi_core_swreset_release();
> +
> +       /*
> +        * configure packet
> +        * info frame video see doc CEA861-D page 65
> +        */
> +       avi_cfg.db1_format = INFOFRAME_AVI_DB1Y_RGB;
> +       avi_cfg.db1_active_info =
> +               INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
> +       avi_cfg.db1_bar_info_dv = INFOFRAME_AVI_DB1B_NO;
> +       avi_cfg.db1_scan_info = INFOFRAME_AVI_DB1S_0;
> +       avi_cfg.db2_colorimetry = INFOFRAME_AVI_DB2C_NO;
> +       avi_cfg.db2_aspect_ratio = INFOFRAME_AVI_DB2M_NO;
> +       avi_cfg.db2_active_fmt_ar = INFOFRAME_AVI_DB2R_SAME;
> +       avi_cfg.db3_itc = INFOFRAME_AVI_DB3ITC_NO;
> +       avi_cfg.db3_ec = INFOFRAME_AVI_DB3EC_XVYUV601;
> +       avi_cfg.db3_q_range = INFOFRAME_AVI_DB3Q_DEFAULT;
> +       avi_cfg.db3_nup_scaling = INFOFRAME_AVI_DB3SC_NO;
> +       avi_cfg.db4_videocode = cfg->video_format;
> +       avi_cfg.db5_pixel_repeat = INFOFRAME_AVI_DB5PR_NO;
> +       avi_cfg.db6_7_line_eoftop = 0;
> +       avi_cfg.db8_9_line_sofbottom = 0;
> +       avi_cfg.db10_11_pixel_eofleft = 0;
> +       avi_cfg.db12_13_pixel_sofright = 0;
> +
> +       hdmi_core_aux_infoframe_avi_config(avi_cfg);
> +
> +       /* enable/repeat the infoframe */
> +       repeat_cfg.avi_infoframe = PACKETENABLE;
> +       repeat_cfg.avi_infoframe_repeat = PACKETREPEATON;
> +
> +       /* wakeup */
> +       repeat_cfg.audio_pkt = PACKETENABLE;
> +       repeat_cfg.audio_pkt_repeat = PACKETREPEATON;
> +       hdmi_core_av_packet_config(repeat_cfg);
> +}
> +
> +static void update_hdmi_timings(struct hdmi_config *cfg,
> +               struct omap_video_timings *timings, int code)
> +{
> +       cfg->ppl = timings->x_res;
> +       cfg->lpp = timings->y_res;
> +       cfg->hbp = timings->hbp;
> +       cfg->hfp = timings->hfp;
> +       cfg->hsw = timings->hsw;
> +       cfg->vbp = timings->vbp;
> +       cfg->vfp = timings->vfp;
> +       cfg->vsw = timings->vsw;
> +       cfg->pixel_clock = timings->pixel_clock;
> +       cfg->v_pol = cea_vesa_timings[code].vsync_pol;
> +       cfg->h_pol = cea_vesa_timings[code].hsync_pol;
> +}
> +
> +void hdmi_lib_exit(void)
> +{
> +
> +}
> +
> +int hdmi_wait_softreset(void)
> +{
> +       /* reset W1 */
> +       REG_FLD_MOD(HDMI_WP_SYSCONFIG, 0x1, 0, 0);
> +
> +       /* wait till SOFTRESET == 0 */
> +       if (hdmi_wait_for_bit_change(HDMI_WP_SYSCONFIG, 0, 0, 0) != 0) {
> +               DSSERR("sysconfig reset failed\n");
> +               return -ENODEV;
> +       }
> +
> +       return 0;
> +}
> +
> +void hdmi_compute_pll(unsigned long clkin, int phy,
> +       int n, struct hdmi_pll_info *pi)
> +{
> +       unsigned long refclk;
> +       u32 mf;
> +
> +       /*
> +        * Input clock is predivided by N + 1
> +        * out put of which is reference clk
> +        */
> +       refclk = clkin / (n + 1);
> +       pi->regn = n;
> +
> +       /*
> +        * multiplier is pixel_clk/ref_clk
> +        * Multiplying by 100 to avoid fractional part removal
> +        */
> +       pi->regm = (phy * 100/(refclk))/100;
> +       pi->regm2 = 1;
> +
> +       /*
> +        * fractional multiplier is remainder of the difference between
> +        * multiplier and actual phy(required pixel clock thus should be
> +        * multiplied by 2^18(262144) divided by the reference clock
> +        */
> +       mf = (phy - pi->regm * refclk) * 262144;
> +       pi->regmf = mf/(refclk);
> +
> +       /*
> +        * Dcofreq should be set to 1 if required pixel clock
> +        * is greater than 1000MHz
> +        */
> +       pi->dcofreq = phy > 1000 * 100;
> +       pi->regsd = ((pi->regm * clkin / 10) / ((n + 1) * 250) + 5) / 10;
> +
> +       DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
> +       DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
> +}
> +
> +static void hdmi_enable_clocks(int enable)
> +{
> +       if (enable)
> +               dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK |
> +                               DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
> +       else
> +               dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK |
> +                               DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
> +}
> +
> +static int hdmi_power_on(struct omap_dss_device *dssdev)
> +{
> +       int r, code = 0;
> +       struct hdmi_pll_info pll_data;
> +       struct omap_video_timings *p;
> +       int clkin, n, phy;
> +
> +       hdmi_enable_clocks(1);
> +
> +       dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
> +
> +       p = &dssdev->panel.timings;
> +
> +       DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
> +               dssdev->panel.timings.x_res,
> +               dssdev->panel.timings.y_res);
> +
> +       DSSDBG("Read EDID as no EDID is not set on poweron\n");
> +       r = hdmi_read_edid(p);
> +       if (r)
> +               return -EIO;
> +
> +       code = get_timings_index();
> +       dssdev->panel.timings = cea_vesa_timings[code].timings;
> +       update_hdmi_timings(&hdmi.cfg, p, code);
> +
> +       clkin = 3840; /* 38.4 MHz */
> +       n = 15; /* this is a constant for our math */
> +       phy = p->pixel_clock;
> +
> +       hdmi_compute_pll(clkin, phy, n, &pll_data);
> +
> +       hdmi_wp_video_stop();
> +
> +       /* config the PLL and PHY first */
> +       r = hdmi_pll_program(&pll_data);
> +       if (r) {
> +               DSSDBG("Failed to lock PLL\n");
> +               return -EIO;
> +       }
> +
> +       r = hdmi_phy_init();
> +       if (r) {
> +               DSSDBG("Failed to start PHY\n");
> +               return -EIO;
> +       }
> +
> +       hdmi.cfg.hdmi_dvi = hdmi.mode;
> +       hdmi.cfg.video_format = hdmi.code;
> +       hdmi_lib_enable(&hdmi.cfg);
> +
> +       /* these settings are independent of overlays */
> +       dss_select_hdmi_venc(1);
> +
> +       /* bypass TV gamma table */
> +       dispc_enable_gamma_table(0);
> +
> +       /* tv size */
> +       dispc_set_digit_size(dssdev->panel.timings.x_res,
> +                       dssdev->panel.timings.y_res);
> +
> +       dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 1);
> +
> +       hdmi_wp_video_start();
> +
> +       return 0;
> +}
> +
> +static void hdmi_power_off(struct omap_dss_device *dssdev)
> +{
> +       dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
> +
> +       hdmi_wp_video_stop();
> +       hdmi_phy_off();
> +       hdmi_wait_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
> +       hdmi_enable_clocks(0);
> +
> +       edid_set = 0;
> +}
> +
> +int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
> +{
> +       int r = 0;
> +
> +       DSSDBG("ENTER hdmi_display_enable\n");
> +
> +       mutex_lock(&hdmi.lock);
> +
> +       r = omap_dss_start_device(dssdev);
> +       if (r) {
> +               DSSDBG("failed to start device\n");
> +               goto err;
> +       }
> +
> +       if (dssdev->platform_enable)
> +               dssdev->platform_enable(dssdev);
> +
> +       r = hdmi_power_on(dssdev);
> +       if (r) {
> +               DSSERR("failed to power on device\n");
> +               goto err;
> +       }
> +
> +err:
> +       mutex_unlock(&hdmi.lock);

The error handling here needs to handle omap_dss_start_device and
platform_enable.

> +
> +       return r;
> +}
> +
> +void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
> +{
> +       DSSDBG("Enter hdmi_display_disable\n");
> +
> +       mutex_lock(&hdmi.lock);
> +
> +       omap_dss_stop_device(dssdev);
> +
> +       if (dssdev->platform_disable)
> +               dssdev->platform_disable(dssdev);
> +
> +       hdmi_power_off(dssdev);
> +

You should do the disabling in reverse order compared to enabling.

> +       mutex_unlock(&hdmi.lock);
> +}
> +
> +int omapdss_hdmi_display_suspend(struct omap_dss_device *dssdev)
> +{
> +       DSSDBG("hdmi_display_suspend\n");
> +
> +       mutex_lock(&hdmi.lock);
> +
> +       omap_dss_stop_device(dssdev);
> +
> +       hdmi_power_off(dssdev);
> +
> +       mutex_unlock(&hdmi.lock);
> +
> +       return 0;
> +}

The code in suspend and resume do not match. And what is the need for
suspend and resume? They are the same as disable and enable.

 Tomi



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2/8] OMAP4 : DSS2 : Add display structure in the board file for OMAP4 sdp
  2011-02-27  9:13   ` Tomi Valkeinen
@ 2011-02-28  5:32     ` K, Mythri P
  0 siblings, 0 replies; 23+ messages in thread
From: K, Mythri P @ 2011-02-28  5:32 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap@vger.kernel.org

Hi Tomi,


On Sun, Feb 27, 2011 at 2:43 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Fri, 2011-02-25 at 08:21 -0600, K, Mythri P wrote:
>> Adding  board file changes for display which adds the display structure
>> with HDMI as the default driver when the display init is called.
>> HDMI GPIO configurations are also done in this file.
>>
>> Signed-off-by: Mythri P K <mythripk@ti.com>
>> ---
>>  arch/arm/mach-omap2/board-4430sdp.c |   82 +++++++++++++++++++++++++++++++++++
>>  1 files changed, 82 insertions(+), 0 deletions(-)
>
> You could move this patch in the end of the set, together with the panda
> board patch.
>
> The prefix "OMAP4: DSS2" is not quite right for this, as this is a board
> file change. And you should mention HDMI in the subject. Perhaps
> something like "OMAP: 4430SDP: Add HDMI support"
>
Sure i will move and change the patch name.
>>
>> diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
>> index 07d1b20..334b6fd 100644
>> --- a/arch/arm/mach-omap2/board-4430sdp.c
>> +++ b/arch/arm/mach-omap2/board-4430sdp.c
>> @@ -35,6 +35,7 @@
>>  #include <plat/common.h>
>>  #include <plat/usb.h>
>>  #include <plat/mmc.h>
>> +#include <plat/display.h>
>>
>>  #include "mux.h"
>>  #include "hsmmc.h"
>> @@ -47,6 +48,8 @@
>>  #define OMAP4SDP_MDM_PWR_EN_GPIO     157
>>  #define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO     184
>>  #define OMAP4_SFH7741_ENABLE_GPIO            188
>> +#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */
>> +#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */
>>
>>  static struct gpio_led sdp4430_gpio_leds[] = {
>>       {
>> @@ -552,6 +555,84 @@ static void __init omap_sfh7741prox_init(void)
>>       }
>>  }
>>
>> +static void sdp4430_hdmi_mux_init(void)
>> +{
>> +     /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
>> +     omap_mux_init_signal("hdmi_hpd",
>> +                     OMAP_PIN_INPUT_PULLUP);
>> +     omap_mux_init_signal("hdmi_cec",
>> +                     OMAP_PIN_INPUT_PULLUP);
>> +     /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
>> +     omap_mux_init_signal("hdmi_ddc_scl",
>> +                     OMAP_PIN_INPUT_PULLUP);
>> +     omap_mux_init_signal("hdmi_ddc_sda",
>> +                     OMAP_PIN_INPUT_PULLUP);
>> +}
>> +
>> +static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
>> +{
>> +     int status;
>
> r is quite often used as a name for return values.
>
Variable status is consistent with other gpio request calls made in the file ,
so it would be good to have status instead of r ,
I have used r in all DSS files though.
>> +
>> +     status = gpio_request_one(HDMI_GPIO_HPD, GPIOF_DIR_OUT,
>> +                                                     "hdmi_gpio_hpd");
>> +     if (status) {
>> +             pr_err("Cannot request GPIO %d\n", HDMI_GPIO_HPD);
>> +             return status;
>> +     }
>> +     status = gpio_request_one(HDMI_GPIO_LS_OE, GPIOF_DIR_OUT,
>> +                                                     "hdmi_gpio_ls_oe");
>> +     if (status) {
>> +             pr_err("Cannot request GPIO %d\n", HDMI_GPIO_LS_OE);
>> +             goto error1;
>> +     }
>> +
>> +     /* The value set a pulse */
>
> I still don't understand that comment. It's not even English.
I was seeing issues where I had to set the pulse [ 101] , But i no
longer see the problem in my tests.
So i shall just enable GPIO.
>
>  Tomi
>
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 4/8] OMAP4 : DSS : HDMI: HDMI driver header file addition
  2011-02-27  9:28   ` Tomi Valkeinen
@ 2011-02-28  5:40     ` K, Mythri P
  0 siblings, 0 replies; 23+ messages in thread
From: K, Mythri P @ 2011-02-28  5:40 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap@vger.kernel.org

Hi Tomi,

On Sun, Feb 27, 2011 at 2:58 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Fri, 2011-02-25 at 08:21 -0600, K, Mythri P wrote:
>> Adding the hdmi interface driver header file (hdmi.h) to the dss driver.
>> Register and timing declaration to be used by the corresponding c file is added in this file.
>>
>> Signed-off-by: Mythri P K <mythripk@ti.com>
>> ---
>>  drivers/video/omap2/dss/hdmi.h |  691 ++++++++++++++++++++++++++++++++++++++++
>>  1 files changed, 691 insertions(+), 0 deletions(-)
>>  create mode 100644 drivers/video/omap2/dss/hdmi.h
>>
>> diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h
>> new file mode 100644
>> index 0000000..7441835
>> --- /dev/null
>> +++ b/drivers/video/omap2/dss/hdmi.h
>> @@ -0,0 +1,691 @@
>> +/*
>> + * hdmi.h
>> + *
>> + * HDMI driver definition for TI OMAP4 processors.
>> + *
>> + * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.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/>.
>> + */
>> +
>> +#ifndef _HDMI_H_
>> +#define _HDMI_H_
>
> This should be more specific. For example, __OMAP2_DSS_HDMI_H would be
> in line with the other includes.
>
ok i shall change
>> +
>> +#include <linux/string.h>
>> +#include <plat/display.h>
>> +
>> +#define HDMI_WP                        0x0
>> +#define HDMI_CORE_SYS          0x400
>> +#define HDMI_CORE_AV           0x900
>> +#define HDMI_PLLCTRL           0x200
>> +#define HDMI_PHY               0x300
>> +
>> +struct hdmi_reg { u16 idx; };
>> +
>> +#define HDMI_REG(idx)                  ((const struct hdmi_reg) { idx })
>> +
>> +/* HDMI Wrapper */
>> +#define HDMI_WP_REG(idx)                       HDMI_REG(HDMI_WP + idx)
>> +
>> +#define HDMI_WP_REVISION                       HDMI_WP_REG(0x0)
>> +#define HDMI_WP_SYSCONFIG                      HDMI_WP_REG(0x10)
>> +#define HDMI_WP_IRQSTATUS_RAW                  HDMI_WP_REG(0x24)
>> +#define HDMI_WP_IRQSTATUS                      HDMI_WP_REG(0x28)
>> +#define HDMI_WP_PWR_CTRL                       HDMI_WP_REG(0x40)
>> +#define HDMI_WP_IRQENABLE_SET                  HDMI_WP_REG(0x2C)
>> +#define HDMI_WP_VIDEO_CFG                      HDMI_WP_REG(0x50)
>> +#define HDMI_WP_VIDEO_SIZE                     HDMI_WP_REG(0x60)
>> +#define HDMI_WP_VIDEO_TIMING_H                 HDMI_WP_REG(0x68)
>> +#define HDMI_WP_VIDEO_TIMING_V                 HDMI_WP_REG(0x6C)
>> +#define HDMI_WP_WP_CLK                         HDMI_WP_REG(0x70)
>> +
>> +/* HDMI IP Core System */
>> +#define HDMI_CORE_SYS_REG(idx)                 HDMI_REG(HDMI_CORE_SYS + idx)
>> +
>> +#define HDMI_CORE_SYS_VND_IDL                  HDMI_CORE_SYS_REG(0x0)
>> +#define HDMI_CORE_SYS_DEV_IDL                  HDMI_CORE_SYS_REG(0x8)
>> +#define HDMI_CORE_SYS_DEV_IDH                  HDMI_CORE_SYS_REG(0xC)
>> +#define HDMI_CORE_SYS_DEV_REV                  HDMI_CORE_SYS_REG(0x10)
>> +#define HDMI_CORE_SYS_SRST                     HDMI_CORE_SYS_REG(0x14)
>> +#define HDMI_CORE_CTRL1                                HDMI_CORE_SYS_REG(0x20)
>> +#define HDMI_CORE_SYS_SYS_STAT                 HDMI_CORE_SYS_REG(0x24)
>> +#define HDMI_CORE_SYS_VID_ACEN                 HDMI_CORE_SYS_REG(0x124)
>> +#define HDMI_CORE_SYS_VID_MODE                 HDMI_CORE_SYS_REG(0x128)
>> +#define HDMI_CORE_SYS_INTR_STATE               HDMI_CORE_SYS_REG(0x1C0)
>> +#define HDMI_CORE_SYS_INTR1                    HDMI_CORE_SYS_REG(0x1C4)
>> +#define HDMI_CORE_SYS_INTR2                    HDMI_CORE_SYS_REG(0x1C8)
>> +#define HDMI_CORE_SYS_INTR3                    HDMI_CORE_SYS_REG(0x1CC)
>> +#define HDMI_CORE_SYS_INTR4                    HDMI_CORE_SYS_REG(0x1D0)
>> +#define HDMI_CORE_SYS_UMASK1                   HDMI_CORE_SYS_REG(0x1D4)
>> +#define HDMI_CORE_SYS_TMDS_CTRL                        HDMI_CORE_SYS_REG(0x208)
>> +#define HDMI_CORE_SYS_DE_DLY                   HDMI_CORE_SYS_REG(0xC8)
>> +#define HDMI_CORE_SYS_DE_CTRL                  HDMI_CORE_SYS_REG(0xCC)
>> +#define HDMI_CORE_SYS_DE_TOP                   HDMI_CORE_SYS_REG(0xD0)
>> +#define HDMI_CORE_SYS_DE_CNTL                  HDMI_CORE_SYS_REG(0xD8)
>> +#define HDMI_CORE_SYS_DE_CNTH                  HDMI_CORE_SYS_REG(0xDC)
>> +#define HDMI_CORE_SYS_DE_LINL                  HDMI_CORE_SYS_REG(0xE0)
>> +#define HDMI_CORE_SYS_DE_LINH_1                        HDMI_CORE_SYS_REG(0xE4)
>> +#define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC                0x1
>> +#define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC                0x1
>> +#define HDMI_CORE_CTRL1_BSEL_24BITBUS          0x1
>> +#define HDMI_CORE_CTRL1_EDGE_RISINGEDGE                0x1
>> +
>> +/* HDMI DDC E-DID */
>> +#define HDMI_CORE_DDC_CMD                      HDMI_CORE_SYS_REG(0x3CC)
>> +#define HDMI_CORE_DDC_STATUS                   HDMI_CORE_SYS_REG(0x3C8)
>> +#define HDMI_CORE_DDC_ADDR                     HDMI_CORE_SYS_REG(0x3B4)
>> +#define HDMI_CORE_DDC_OFFSET                   HDMI_CORE_SYS_REG(0x3BC)
>> +#define HDMI_CORE_DDC_COUNT1                   HDMI_CORE_SYS_REG(0x3C0)
>> +#define HDMI_CORE_DDC_COUNT2                   HDMI_CORE_SYS_REG(0x3C4)
>> +#define HDMI_CORE_DDC_DATA                     HDMI_CORE_SYS_REG(0x3D0)
>> +#define HDMI_CORE_DDC_SEGM                     HDMI_CORE_SYS_REG(0x3B8)
>> +
>> +/* HDMI IP Core Audio Video */
>> +#define HDMI_CORE_AV_REG(idx)                  HDMI_REG(HDMI_CORE_AV + idx)
>> +
>> +#define HDMI_CORE_AV_HDMI_CTRL                 HDMI_CORE_AV_REG(0xBC)
>> +#define HDMI_CORE_AV_DPD                       HDMI_CORE_AV_REG(0xF4)
>> +#define HDMI_CORE_AV_PB_CTRL1                  HDMI_CORE_AV_REG(0xF8)
>> +#define HDMI_CORE_AV_PB_CTRL2                  HDMI_CORE_AV_REG(0xFC)
>> +#define HDMI_CORE_AV_AVI_TYPE                  HDMI_CORE_AV_REG(0x100)
>> +#define HDMI_CORE_AV_AVI_VERS                  HDMI_CORE_AV_REG(0x104)
>> +#define HDMI_CORE_AV_AVI_LEN                   HDMI_CORE_AV_REG(0x108)
>> +#define HDMI_CORE_AV_AVI_CHSUM                 HDMI_CORE_AV_REG(0x10C)
>> +#define HDMI_CORE_AV_AVI_DBYTE(n)              HDMI_CORE_AV_REG(n * 4 + 0x110)
>> +#define HDMI_CORE_AV_AVI_DBYTE_NELEMS          HDMI_CORE_AV_REG(15)
>> +#define HDMI_CORE_AV_SPD_DBYTE                 HDMI_CORE_AV_REG(0x190)
>> +#define HDMI_CORE_AV_SPD_DBYTE_NELEMS          HDMI_CORE_AV_REG(27)
>> +#define HDMI_CORE_AV_MPEG_DBYTE                        HDMI_CORE_AV_REG(0x290)
>> +#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS         HDMI_CORE_AV_REG(27)
>> +#define HDMI_CORE_AV_GEN_DBYTE                 HDMI_CORE_AV_REG(0x300)
>> +#define HDMI_CORE_AV_GEN_DBYTE_NELEMS          HDMI_CORE_AV_REG(31)
>> +#define HDMI_CORE_AV_GEN2_DBYTE                        HDMI_CORE_AV_REG(0x380)
>> +#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS         HDMI_CORE_AV_REG(31)
>> +#define HDMI_CORE_AV_ACR_CTRL                  HDMI_CORE_AV_REG(0x4)
>> +#define HDMI_CORE_AV_FREQ_SVAL                 HDMI_CORE_AV_REG(0x8)
>> +#define HDMI_CORE_AV_N_SVAL1                   HDMI_CORE_AV_REG(0xC)
>> +#define HDMI_CORE_AV_N_SVAL2                   HDMI_CORE_AV_REG(0x10)
>> +#define HDMI_CORE_AV_N_SVAL3                   HDMI_CORE_AV_REG(0x14)
>> +#define HDMI_CORE_AV_CTS_SVAL1                 HDMI_CORE_AV_REG(0x18)
>> +#define HDMI_CORE_AV_CTS_SVAL2                 HDMI_CORE_AV_REG(0x1C)
>> +#define HDMI_CORE_AV_CTS_SVAL3                 HDMI_CORE_AV_REG(0x20)
>> +#define HDMI_CORE_AV_CTS_HVAL1                 HDMI_CORE_AV_REG(0x24)
>> +#define HDMI_CORE_AV_CTS_HVAL2                 HDMI_CORE_AV_REG(0x28)
>> +#define HDMI_CORE_AV_CTS_HVAL3                 HDMI_CORE_AV_REG(0x2C)
>> +#define HDMI_CORE_AV_AUD_MODE                  HDMI_CORE_AV_REG(0x50)
>> +#define HDMI_CORE_AV_SPDIF_CTRL                        HDMI_CORE_AV_REG(0x54)
>> +#define HDMI_CORE_AV_HW_SPDIF_FS               HDMI_CORE_AV_REG(0x60)
>> +#define HDMI_CORE_AV_SWAP_I2S                  HDMI_CORE_AV_REG(0x64)
>> +#define HDMI_CORE_AV_SPDIF_ERTH                        HDMI_CORE_AV_REG(0x6C)
>> +#define HDMI_CORE_AV_I2S_IN_MAP                        HDMI_CORE_AV_REG(0x70)
>> +#define HDMI_CORE_AV_I2S_IN_CTRL               HDMI_CORE_AV_REG(0x74)
>> +#define HDMI_CORE_AV_I2S_CHST0                 HDMI_CORE_AV_REG(0x78)
>> +#define HDMI_CORE_AV_I2S_CHST1                 HDMI_CORE_AV_REG(0x7C)
>> +#define HDMI_CORE_AV_I2S_CHST2                 HDMI_CORE_AV_REG(0x80)
>> +#define HDMI_CORE_AV_I2S_CHST4                 HDMI_CORE_AV_REG(0x84)
>> +#define HDMI_CORE_AV_I2S_CHST5                 HDMI_CORE_AV_REG(0x88)
>> +#define HDMI_CORE_AV_ASRC                      HDMI_CORE_AV_REG(0x8C)
>> +#define HDMI_CORE_AV_I2S_IN_LEN                        HDMI_CORE_AV_REG(0x90)
>> +#define HDMI_CORE_AV_HDMI_CTRL                 HDMI_CORE_AV_REG(0xBC)
>> +#define HDMI_CORE_AV_AUDO_TXSTAT               HDMI_CORE_AV_REG(0xC0)
>> +#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1          HDMI_CORE_AV_REG(0xCC)
>> +#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2          HDMI_CORE_AV_REG(0xD0)
>> +#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3          HDMI_CORE_AV_REG(0xD4)
>> +#define HDMI_CORE_AV_TEST_TXCTRL               HDMI_CORE_AV_REG(0xF0)
>> +#define HDMI_CORE_AV_DPD                       HDMI_CORE_AV_REG(0xF4)
>> +#define HDMI_CORE_AV_PB_CTRL1                  HDMI_CORE_AV_REG(0xF8)
>> +#define HDMI_CORE_AV_PB_CTRL2                  HDMI_CORE_AV_REG(0xFC)
>> +#define HDMI_CORE_AV_AVI_TYPE                  HDMI_CORE_AV_REG(0x100)
>> +#define HDMI_CORE_AV_AVI_VERS                  HDMI_CORE_AV_REG(0x104)
>> +#define HDMI_CORE_AV_AVI_LEN                   HDMI_CORE_AV_REG(0x108)
>> +#define HDMI_CORE_AV_AVI_CHSUM                 HDMI_CORE_AV_REG(0x10C)
>> +#define HDMI_CORE_AV_SPD_TYPE                  HDMI_CORE_AV_REG(0x180)
>> +#define HDMI_CORE_AV_SPD_VERS                  HDMI_CORE_AV_REG(0x184)
>> +#define HDMI_CORE_AV_SPD_LEN                   HDMI_CORE_AV_REG(0x188)
>> +#define HDMI_CORE_AV_SPD_CHSUM                 HDMI_CORE_AV_REG(0x18C)
>> +#define HDMI_CORE_AV_MPEG_TYPE                 HDMI_CORE_AV_REG(0x280)
>> +#define HDMI_CORE_AV_MPEG_VERS                 HDMI_CORE_AV_REG(0x284)
>> +#define HDMI_CORE_AV_MPEG_LEN                  HDMI_CORE_AV_REG(0x288)
>> +#define HDMI_CORE_AV_MPEG_CHSUM                        HDMI_CORE_AV_REG(0x28C)
>> +#define HDMI_CORE_AV_CP_BYTE1                  HDMI_CORE_AV_REG(0x37C)
>> +#define HDMI_CORE_AV_CEC_ADDR_ID               HDMI_CORE_AV_REG(0x3FC)
>> +#define HDMI_CORE_AV_SPD_DBYTE_ELSIZE          0x4
>> +#define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE         0x4
>> +#define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE         0x4
>> +#define HDMI_CORE_AV_GEN_DBYTE_ELSIZE          0x4
>> +
>> +/* PLL */
>> +#define HDMI_PLL_REG(idx)                      HDMI_REG(HDMI_PLLCTRL + idx)
>> +
>> +#define PLLCTRL_PLL_CONTROL                    HDMI_PLL_REG(0x0)
>> +#define PLLCTRL_PLL_STATUS                     HDMI_PLL_REG(0x4)
>> +#define PLLCTRL_PLL_GO                         HDMI_PLL_REG(0x8)
>> +#define PLLCTRL_CFG1                           HDMI_PLL_REG(0xC)
>> +#define PLLCTRL_CFG2                           HDMI_PLL_REG(0x10)
>> +#define PLLCTRL_CFG3                           HDMI_PLL_REG(0x14)
>> +#define PLLCTRL_CFG4                           HDMI_PLL_REG(0x20)
>> +
>> +/* HDMI PHY */
>> +#define HDMI_PHY_REG(idx)                      HDMI_REG(HDMI_PHY + idx)
>> +
>> +#define HDMI_TXPHY_TX_CTRL                     HDMI_PHY_REG(0x0)
>> +#define HDMI_TXPHY_DIGITAL_CTRL                        HDMI_PHY_REG(0x4)
>> +#define HDMI_TXPHY_POWER_CTRL                  HDMI_PHY_REG(0x8)
>> +#define HDMI_TXPHY_PAD_CFG_CTRL                        HDMI_PHY_REG(0xC)
>> +
>> +/* HDMI EDID Length  */
>> +#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 REG_FLD_MOD(idx, val, start, end) \
>> +       hdmi_write_reg(idx, FLD_MOD(hdmi_read_reg(idx), val, start, end))
>> +
>> +u8             edid[HDMI_EDID_MAX_LENGTH] = {0};
>> +u8             edid_set;
>> +u8             header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0};
>> +struct         omap_video_timings edid_timings;
>
> Global variables in a header file? This cannot be right.
I shall move this to corresponding c files.
>
>> +
>> +/* HDMI timing structure */
>> +struct hdmi_timings {
>> +       struct omap_video_timings timings;
>> +       int vsync_pol;
>> +       int hsync_pol;
>> +};
>> +
>> +/*
>> + * Logic for the below structure
>> + * user enters the CEA or VESA timings by specifying
>> + * the hdmicode which corresponds to CEA/VESA timings
>> + * please refer to section 6.3 in HDMI 1.3 specification for timing code.
>> + * There is a correspondence between CEA/VESA timing and code.
>> + * In the below structure, cea_vesa_timings corresponds to all
>> + * The OMAP4 supported timing  CEA and VESA timing values.
>> + * code_cea corresponds to the CEA code entered by the user,
>> + * The use of it is to get the timing from the cea_vesa_timing array.
>> + * Similarly for code_vesa.
>> + * code_index is backmapping, Once EDID is read from the TV
>> + * EDID is parsed to find the timing values to map it back to the
>> + * corresponding CEA or VESA index this structure is used.
>> + */
>> +
>> +/*
>> + * This is the structure which has all supported timing
>> + * values that OMAP4 supports
>> + */
>> +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, 112, 64, 256, 6 , 3, 18}, 1, 1},
>> +       { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36}, 1, 1},
>> +       { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38}, 1, 1},
>> +       { {1024, 768, 65000, 136, 24, 160, 6, 3, 29}, 0, 0},
>> +       { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32}, 1, 0},
>> +       { {1440, 900, 106500, 152, 80, 232, 6, 3, 25}, 1, 0},
>> +       { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30}, 1, 0},
>> +       { {1366, 768, 85500, 143, 70, 213, 3, 3, 24}, 1, 1},
>> +       { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36}, 1, 1},
>> +       { {1280, 768, 68250, 32, 48, 80, 7, 3, 12}, 0, 1},
>> +       { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23}, 0, 1},
>> +       { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21}, 0, 1},
>> +       { {1280, 800, 79500, 32, 48, 80, 6, 3, 14}, 0, 1},
>> +       { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}
>> +};
>> +
>> +/*
>> + * This is a static mapping array which maps the timing values
>> + * with corresponding CEA / VESA code
>> + */
>> +static int code_index[OMAP_HDMI_TIMINGS_NB] = {
>> +       1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32,
>> +       /* <--15 CEA 17--> vesa*/
>> +       4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A,
>> +       0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B
>> +};
>> +
>> +/*
>> + * This is reverse static mapping which maps the CEA / VESA code
>> + * to the corresponding timing values
>> + */
>> +static int code_cea[39] = {
>> +       -1,  0,  3,  3,  2,  8,  5,  5, -1, -1,
>> +       -1, -1, -1, -1, -1, -1,  9, 10, 10,  1,
>> +       7,   6,  6, -1, -1, -1, -1, -1, -1, 11,
>> +       11, 12, 14, -1, -1, 13, 13,  4,  4
>> +};
>> +
>> +int code_vesa[85] = {
>> +       -1, -1, -1, -1, 15, -1, -1, -1, -1, 16,
>> +       -1, -1, -1, -1, 17, -1, 23, -1, -1, -1,
>> +       -1, -1, 29, 18, -1, -1, -1, 32, 19, -1,
>> +       -1, -1, 21, -1, -1, 22, -1, -1, -1, 20,
>> +       -1, 30, 24, -1, -1, -1, -1, 25, -1, -1,
>> +       -1, -1, -1, -1, -1, -1, -1, 31, 26, -1,
>> +       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
>> +       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
>> +       -1, 27, 28, -1, 33};
>
> And even more global tables...
I shall move this to c file too.
>
>> +
>> +enum hdmi_phypwr {
>> +       HDMI_PHYPWRCMD_OFF = 0,
>> +       HDMI_PHYPWRCMD_LDOON = 1,
>> +       HDMI_PHYPWRCMD_TXON = 2
>> +};
>> +
>> +enum hdmi_pll_pwr {
>> +       HDMI_PLLPWRCMD_ALLOFF = 0,
>> +       HDMI_PLLPWRCMD_PLLONLY = 1,
>> +       HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
>> +       HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
>> +};
>> +
>> +enum hdmi_core_inputbus_width {
>> +       HDMI_INPUT_8BIT = 0,
>> +       HDMI_INPUT_10BIT = 1,
>> +       HDMI_INPUT_12BIT = 2
>> +};
>> +
>> +enum hdmi_core_dither_trunc {
>> +       HDMI_OUTPUTTRUNCATION_8BIT = 0,
>> +       HDMI_OUTPUTTRUNCATION_10BIT = 1,
>> +       HDMI_OUTPUTTRUNCATION_12BIT = 2,
>> +       HDMI_OUTPUTDITHER_8BIT = 3,
>> +       HDMI_OUTPUTDITHER_10BIT = 4,
>> +       HDMI_OUTPUTDITHER_12BIT = 5
>> +};
>> +
>> +enum hdmi_core_deepcolor_ed {
>> +       HDMI_DEEPCOLORPACKECTDISABLE = 0,
>> +       HDMI_DEEPCOLORPACKECTENABLE = 1
>> +};
>> +
>> +enum hdmi_core_packet_mode {
>> +       HDMI_PACKETMODERESERVEDVALUE = 0,
>> +       HDMI_PACKETMODE24BITPERPIXEL = 4,
>> +       HDMI_PACKETMODE30BITPERPIXEL = 5,
>> +       HDMI_PACKETMODE36BITPERPIXEL = 6,
>> +       HDMI_PACKETMODE48BITPERPIXEL = 7
>> +};
>> +
>> +enum hdmi_core_hdmi_dvi {
>> +       HDMI_DVI = 0,
>> +       HDMI_HDMI = 1
>> +};
>> +
>> +enum hdmi_core_tclkselclkmult {
>> +       FPLL05IDCK = 0,
>> +       FPLL10IDCK = 1,
>> +       FPLL20IDCK = 2,
>> +       FPLL40IDCK = 3
>> +};
>> +
>> +enum hdmi_core_fs {
>> +       FS_32000 = 0,
>> +       FS_44100 = 1
>> +};
>> +
>> +enum hdmi_core_layout {
>> +       LAYOUT_2CH = 0,
>> +       LAYOUT_8CH = 1
>> +};
>> +
>> +enum hdmi_core_cts_mode {
>> +       CTS_MODE_HW = 0,
>> +       CTS_MODE_SW = 1
>> +};
>
> Enums in C are not inside any namespace. That's why enums need to have
> some kind of prefix, just like defines.
I shall add a HDMI prefix.
>
>  Tomi
>
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 5/8] OMAP4 : DSS2 : HDMI: HDMI driver addition in the DSS drivers interface
  2011-02-27 10:17   ` Tomi Valkeinen
@ 2011-02-28  6:11     ` K, Mythri P
  2011-02-28  6:27       ` Tomi Valkeinen
  0 siblings, 1 reply; 23+ messages in thread
From: K, Mythri P @ 2011-02-28  6:11 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap@vger.kernel.org

Hi Tomi,

On Sun, Feb 27, 2011 at 3:47 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Fri, 2011-02-25 at 08:21 -0600, K, Mythri P wrote:
>> Adding the hdmi interface driver(hdmi.c) to the dss driver.
>> It configures the audio and video portion of HDMI in the
>> display header file to be accessed by the panels.
>>
>> Signed-off-by: Mythri P K <mythripk@ti.com>
>> ---
>>  drivers/video/omap2/dss/Kconfig   |    8 +
>>  drivers/video/omap2/dss/Makefile  |    1 +
>>  drivers/video/omap2/dss/display.c |    3 +
>>  drivers/video/omap2/dss/dss.h     |   33 +
>>  drivers/video/omap2/dss/hdmi.c    | 1276 +++++++++++++++++++++++++++++++++++++
>>  drivers/video/omap2/dss/hdmi.h    |    9 +
>>  6 files changed, 1330 insertions(+), 0 deletions(-)
>>  create mode 100644 drivers/video/omap2/dss/hdmi.c
>>
>> diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
>> index 0d031b2..fe1ab09 100644
>> --- a/drivers/video/omap2/dss/Kconfig
>> +++ b/drivers/video/omap2/dss/Kconfig
>> @@ -60,6 +60,14 @@ config OMAP2_DSS_VENC
>>         help
>>           OMAP Video Encoder support for S-Video and composite TV-out.
>>
>> +config OMAP2_DSS_HDMI
>> +       bool "HDMI support"
>> +       depends on ARCH_OMAP4
>> +        default n
>> +       help
>> +         HDMI Interface. This adds the High Definition Multimedia Interface.
>> +         See http://www.hdmi.org/ for HDMI specification.
>> +
>>  config OMAP2_DSS_SDI
>>         bool "SDI support"
>>         depends on ARCH_OMAP3
>> diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
>> index 7db17b5..5998b69 100644
>> --- a/drivers/video/omap2/dss/Makefile
>> +++ b/drivers/video/omap2/dss/Makefile
>> @@ -5,3 +5,4 @@ omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
>>  omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
>>  omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
>>  omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
>> +omapdss-$(CONFIG_OMAP2_DSS_HDMI) += hdmi.o
>> diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
>> index e10b303..cbab61a 100644
>> --- a/drivers/video/omap2/dss/display.c
>> +++ b/drivers/video/omap2/dss/display.c
>> @@ -447,6 +447,9 @@ void dss_init_device(struct platform_device *pdev,
>>                 r = dsi_init_display(dssdev);
>>                 break;
>>  #endif
>> +       case OMAP_DISPLAY_TYPE_HDMI:
>> +               r = hdmi_init_display(dssdev);
>> +               break;
>>         default:
>>                 BUG();
>>         }
>> diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
>> index d199ba7..171877e 100644
>> --- a/drivers/video/omap2/dss/dss.h
>> +++ b/drivers/video/omap2/dss/dss.h
>> @@ -163,6 +163,16 @@ struct dsi_clock_info {
>>         bool use_dss2_fck;
>>  };
>>
>> +/* HDMI PLL structure */
>> +struct hdmi_pll_info {
>> +       u16 regn;
>> +       u16 regm;
>> +       u32 regmf;
>> +       u16 regm2;
>> +       u16 regsd;
>> +       u16 dcofreq;
>> +};
>> +
>>  struct seq_file;
>>  struct platform_device;
>>
>> @@ -428,6 +438,29 @@ static inline void venc_uninit_platform_driver(void)
>>  }
>>  #endif
>>
>> +/* HDMI */
>> +#ifdef CONFIG_OMAP2_DSS_HDMI
>> +int hdmi_init_platform_driver(void);
>> +void hdmi_uninit_platform_driver(void);
>> +int hdmi_init_display(struct omap_dss_device *dssdev);
>> +#else
>> +static inline int hdmi_init_display(struct omap_dss_device *dssdev)
>> +{
>> +       return 0;
>> +}
>> +static inline int hdmi_init_platform_driver(void)
>> +{
>> +       return 0;
>> +}
>> +static inline void hdmi_uninit_platform_driver(void)
>> +{
>> +}
>> +#endif
>> +int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
>> +void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
>> +int omapdss_hdmi_display_suspend(struct omap_dss_device *dssdev);
>> +int omapdss_hdmi_display_resume(struct omap_dss_device *dssdev);
>> +
>>  /* RFBI */
>>  #ifdef CONFIG_OMAP2_DSS_RFBI
>>  int rfbi_init_platform_driver(void);
>> diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
>> new file mode 100644
>> index 0000000..1cd861f
>> --- /dev/null
>> +++ b/drivers/video/omap2/dss/hdmi.c
>> @@ -0,0 +1,1276 @@
>> +/*
>> + * 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
>
> Who is Yong Zhi and where's his signed-off-by?
Yong zhi had written some of the functions in this file , which was in
a library.He no longer works on the driver though .
>
>> + *     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 <plat/display.h>
>> +
>> +#include "dss.h"
>> +#include "hdmi.h"
>> +
>> +static struct {
>> +       struct mutex lock;
>> +       struct omap_display_platform_data *pdata;
>> +       struct platform_device *pdev;
>> +       void __iomem *base_wp;  /* HDMI wrapper */
>> +       int code;
>> +       int mode;
>> +       struct hdmi_config cfg;
>> +} hdmi;
>> +
>> +static inline void hdmi_write_reg(const struct hdmi_reg idx, u32 val)
>> +{
>> +       __raw_writel(val, hdmi.base_wp + idx.idx);
>> +}
>> +
>> +static inline u32 hdmi_read_reg(const struct hdmi_reg idx)
>> +{
>> +       u32 l;
>> +       l = __raw_readl(hdmi.base_wp + idx.idx);
>> +       return l;
>> +}
>
> No need for the l variable.
sorry should have checked.
>
>> +
>> +static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx,
>> +                               int b2, int b1, u32 val)
>> +{
>> +       u32 t = 0;
>> +       while (val != FLD_GET(hdmi_read_reg(idx), b2, b1)) {
>
> There's REG_GET macro used in other DSS files to read bits from the
> registers.
Hmm i see that in dsi.c REG_GET is defined to do the same,
#define REG_GET(idx, start, end) \
	FLD_GET(dsi_read_reg(idx), start, end)
So should this be fine of should i define a new REG_GET ?
>
>> +               udelay(1);
>> +               if (t++ > 10000)
>> +                       return !val;
>> +       }
>> +       return val;
>> +}
>> +
>> +int hdmi_init_display(struct omap_dss_device *dssdev)
>> +{
>> +       DSSDBG("init_display\n");
>> +
>> +       return 0;
>> +}
>> +
>> +static int hdmi_pll_init(int refsel, int dcofreq,
>> +               struct hdmi_pll_info *fmt, u16 sd)
>> +{
>> +       u32 r;
>> +
>> +       /* PLL start always use manual mode */
>> +       REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
>> +
>> +       r = hdmi_read_reg(PLLCTRL_CFG1);
>> +       r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
>> +       r = FLD_MOD(r, fmt->regn, 8, 1);  /* CFG1_PLL_REGN */
>> +
>> +       hdmi_write_reg(PLLCTRL_CFG1, r);
>> +
>> +       r = hdmi_read_reg(PLLCTRL_CFG2);
>> +
>> +       r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
>> +       r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
>> +       r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
>> +
>> +       if (dcofreq) {
>> +               /* divider programming for frequency beyond 1000Mhz */
>> +               REG_FLD_MOD(PLLCTRL_CFG3, sd, 17, 10);
>> +               r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
>> +       } else {
>> +               r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
>> +       }
>> +
>> +       hdmi_write_reg(PLLCTRL_CFG2, r);
>> +
>> +       r = hdmi_read_reg(PLLCTRL_CFG4);
>> +       r = FLD_MOD(r, fmt->regm2, 24, 18);
>> +       r = FLD_MOD(r, fmt->regmf, 17, 0);
>> +
>> +       hdmi_write_reg(PLLCTRL_CFG4, r);
>> +
>> +       /* go now */
>> +       REG_FLD_MOD(PLLCTRL_PLL_GO, 0x1, 0, 0);
>> +
>> +       /* wait for bit change */
>> +       if (hdmi_wait_for_bit_change(PLLCTRL_PLL_GO, 0, 0, 1) != 1) {
>> +               DSSERR("PLL GO bit not set\n");
>> +               return -ETIMEDOUT;
>> +       }
>> +
>> +       /* Wait till the lock bit is set in PLL status */
>> +       if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
>> +               DSSWARN("cannot lock PLL\n");
>> +               DSSWARN("CFG1 0x%x\n",
>> +                       hdmi_read_reg(PLLCTRL_CFG1));
>> +               DSSWARN("CFG2 0x%x\n",
>> +                       hdmi_read_reg(PLLCTRL_CFG2));
>> +               DSSWARN("CFG4 0x%x\n",
>> +                       hdmi_read_reg(PLLCTRL_CFG4));
>> +               return -ETIMEDOUT;
>> +       }
>> +
>> +       DSSDBG("PLL locked!\n");
>> +
>> +       return 0;
>> +}
>> +
>> +static int hdmi_pll_reset(void)
>> +{
>> +       /* SYSRESET  controlled by power FSM */
>> +       REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 3, 3);
>> +
>> +       /* READ 0x0 reset is in progress */
>> +       if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) {
>> +               DSSERR("Failed to sysreset PLL\n");
>> +               return -ETIMEDOUT;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int hdmi_phy_init(void)
>> +{
>> +       u16 r = 0;
>> +
>> +       /*
>> +        * wait till PHY_PWR_STATUS=LDOON
>> +        * HDMI_PHYPWRCMD_LDOON = 1
>> +        */
>> +       r = hdmi_wait_phy_pwr(1);
>
> Why doesn't hdmi_wait_phy_pwr use an enum?
I shall change.
>
>> +       if (r)
>> +               return r;
>> +
>> +       /* wait till PHY_PWR_STATUS=TXON */
>> +       r = hdmi_wait_phy_pwr(2);
>> +       if (r)
>> +               return r;
>> +
>> +       /*
>> +        * Read address 0 in order to get the SCP reset done completed
>> +        * Dummy access performed to make sure reset is done
>> +        */
>> +       hdmi_read_reg(HDMI_TXPHY_TX_CTRL);
>> +
>> +       /*
>> +        * Write to phy address 0 to configure the clock
>> +        * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field
>> +        */
>> +       REG_FLD_MOD(HDMI_TXPHY_TX_CTRL, 0x1, 31, 30);
>> +
>> +       /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */
>> +       hdmi_write_reg(HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000);
>> +
>> +       /* Setup max LDO voltage */
>> +       REG_FLD_MOD(HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0);
>> +
>> +       /* Write to phy address 3 to change the polarity control */
>> +       REG_FLD_MOD(HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
>> +
>> +       return 0;
>> +}
>> +
>> +int hdmi_pll_program(struct hdmi_pll_info *fmt)
>
> This, and some other functions in this file, could be static.
Hmm ok i shall see what all functions will not be needed from other
files and make them static.
>
>> +{
>> +       u16 r = 0;
>> +       int refsel;
>> +
>> +       /* wait for wrapper reset */
>> +       hdmi_wait_softreset();
>> +
>> +       /* power off PLL */
>> +       r = hdmi_wait_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
>> +       if (r)
>> +               return r;
>> +
>> +       /* power on PLL */
>> +       r = hdmi_wait_pll_pwr(HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
>> +       if (r)
>> +               return r;
>> +
>> +       hdmi_pll_reset();
>> +
>> +       refsel = 0x3; /* select SYSCLK reference */
>> +
>> +       r = hdmi_pll_init(refsel, fmt->dcofreq, fmt, fmt->regsd);
>> +       if (r)
>> +               return r;
>> +
>> +       return 0;
>> +}
>> +
>> +static void hdmi_phy_off(void)
>> +{
>> +       /*
>> +        * Wait till PHY_PWR_STATUS=OFF
>> +        * HDMI_PHYPWRCMD_OFF = 0
>> +        */
>> +       hdmi_wait_phy_pwr(0);
>> +}
>> +
>> +int hdmi_core_ddc_edid(u8 *pEDID, int ext)
>> +{
>> +       u32 i, j, l;
>> +       char checksum = 0;
>> +       u32 offset = 0;
>> +
>> +       /* Turn on CLK for DDC */
>> +       REG_FLD_MOD(HDMI_CORE_AV_DPD, 0x7, 2, 0);
>> +
>> +       /* HACK : DDC needs time to stablize */
>> +       mdelay(10);
>
> So what is the reason for this? It's a sleep that for unknown reason
> make the code work? Or is there an idea why this is needed?
This is the time it needs to stabilize DDC, else most of the time it
reads a 0 or
wrong shifted values , so i have prefixed with a HACK.
>
>> +
>> +       if (!ext) {
>> +               /* Clk SCL Devices */
>> +               REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0xA, 3, 0);
>> +
>> +               /* HDMI_CORE_DDC_STATUS_IN_PROG No timer needed */
>> +               if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
>> +                                               4, 4, 0) != 0) {
>> +                       DSSERR("Failed to program DDC\n");
>> +                       return -ETIMEDOUT;
>> +               }
>> +
>> +               /* Clear FIFO */
>> +               REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x9, 3, 0);
>> +
>> +               /* HDMI_CORE_DDC_STATUS_IN_PROG */
>> +               if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS,
>> +                                               4, 4, 0) != 0) {
>> +                       DSSERR("Failed to program DDC\n");
>> +                       return -ETIMEDOUT;
>> +               }
>> +
>> +       } else {
>> +               if (ext % 2 != 0)
>> +                       offset = 0x80;
>> +       }
>> +
>> +       /* Load Segment Address Register */
>> +       REG_FLD_MOD(HDMI_CORE_DDC_SEGM, ext/2, 7, 0);
>> +
>> +       /* Load Slave Address Register */
>> +       REG_FLD_MOD(HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
>> +
>> +       /* Load Offset Address Register */
>> +       REG_FLD_MOD(HDMI_CORE_DDC_OFFSET, offset, 7, 0);
>> +
>> +       /* Load Byte Count */
>> +       REG_FLD_MOD(HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
>> +       REG_FLD_MOD(HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
>> +
>> +       /* Set DDC_CMD */
>> +       if (ext)
>> +               REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x4, 3, 0);
>> +       else
>> +               REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x2, 3, 0);
>> +
>> +       /*
>> +        * Do not optimize this part of the code, seems
>> +        * DDC bus needs some time to get stabilized
>> +        */
>> +       l = hdmi_read_reg(HDMI_CORE_DDC_STATUS);
>> +
>> +       /* HDMI_CORE_DDC_STATUS_BUS_LOW */
>> +       if (FLD_GET(l, 6, 6) == 1) {
>> +               DSSWARN("I2C Bus Low?\n");
>> +               return -EIO;
>> +       }
>> +       /* HDMI_CORE_DDC_STATUS_NO_ACK */
>> +       if (FLD_GET(l, 5, 5) == 1) {
>> +               DSSWARN("I2C No Ack\n");
>> +               return -EIO;
>> +       }
>> +
>> +       i = ext * 128;
>> +       j = 0;
>> +       while (((FLD_GET(hdmi_read_reg(HDMI_CORE_DDC_STATUS), 4, 4) == 1) ||
>> +               (FLD_GET(hdmi_read_reg(HDMI_CORE_DDC_STATUS), 2, 2) == 0)) &&
>> +                                                               j < 128) {
>> +               if (FLD_GET(hdmi_read_reg(HDMI_CORE_DDC_STATUS), 2, 2) == 0) {
>> +                       /* FIFO not empty */
>> +                       pEDID[i++] = FLD_GET(
>> +                               hdmi_read_reg(HDMI_CORE_DDC_DATA), 7, 0);
>> +                       j++;
>> +               }
>> +       }
>> +
>> +       for (j = 0; j < 128; j++)
>> +               checksum += pEDID[j];
>> +
>> +       if (checksum != 0) {
>> +               DSSERR("E-EDID checksum failed!!\n");
>> +               return -EIO;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +int read_edid(u8 *pEDID, u16 max_length)
>> +{
>> +       int r = 0, n = 0, i = 0;
>> +       int max_ext_blocks = (max_length / 128) - 1;
>> +
>> +       r = hdmi_core_ddc_edid(pEDID, 0);
>> +       if (r) {
>> +               return -EIO;
>> +       } else {
>> +               n = pEDID[0x7e];
>> +
>> +               /*
>> +                * README: need to comply with max_length set by the caller.
>> +                * Better implementation should be to allocate necessary
>> +                * memory to store EDID according to nb_block field found
>> +                * in first block
>> +                */
>> +
>> +               if (n > max_ext_blocks)
>> +                       n = max_ext_blocks;
>> +
>> +               for (i = 1; i <= n; i++) {
>> +                       r = hdmi_core_ddc_edid(pEDID, i);
>> +                       if (r)
>> +                               return -EIO;
>> +               }
>> +       }
>> +       return 0;
>> +}
>> +
>> +static inline void print_omap_video_timings(struct omap_video_timings *timings)
>
> Why is this inline?
Its only a print function , called many times by the driver. Do you
see any reason not to make it inline?
>
>> +{
>> +       DSSINFO("Timing Info:\n");
>> +       DSSINFO("pixel_clk = %d\n", timings->pixel_clock);
>> +       DSSINFO("  x_res     = %d\n", timings->x_res);
>> +       DSSINFO("  y_res     = %d\n", timings->y_res);
>> +       DSSINFO("  hfp       = %d\n", timings->hfp);
>> +       DSSINFO("  hsw       = %d\n", timings->hsw);
>> +       DSSINFO("  hbp       = %d\n", timings->hbp);
>> +       DSSINFO("  vfp       = %d\n", timings->vfp);
>> +       DSSINFO("  vsw       = %d\n", timings->vsw);
>> +       DSSINFO("  vbp       = %d\n", timings->vbp);
>> +}
>> +
>> +static int get_timings_index(void)
>> +{
>> +       int code;
>> +
>> +       if (hdmi.mode == 0)
>> +               code = code_vesa[hdmi.code];
>> +       else
>> +               code = code_cea[hdmi.code];
>> +
>> +       if (code == -1) {
>> +               code = 9;
>> +               /* HDMI code 16 corresponds to 1920 * 1080 */
>> +               hdmi.code = 16;
>> +               /* HDMI mode 1 corresponds to HDMI 0 to DVI */
>> +               hdmi.mode = HDMI_HDMI;
>> +       }
>> +       return code;
>> +}
>> +
>> +static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
>> +{
>> +       int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0;
>> +       int timing_vsync = 0, timing_hsync = 0;
>> +       struct omap_video_timings temp;
>> +       struct hdmi_cm cm = {-1};
>> +       DSSDBG("hdmi_get_code\n");
>> +
>> +       for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) {
>> +               temp = cea_vesa_timings[i].timings;
>> +               if ((temp.pixel_clock == timing->pixel_clock) &&
>> +                       (temp.x_res == timing->x_res) &&
>> +                       (temp.y_res == timing->y_res)) {
>> +
>> +                       temp_hsync = temp.hfp + temp.hsw + temp.hbp;
>> +                       timing_hsync = timing->hfp + timing->hsw + timing->hbp;
>> +                       temp_vsync = temp.vfp + temp.vsw + temp.vbp;
>> +                       timing_vsync = timing->vfp + timing->vsw + timing->vbp;
>> +
>> +                       DSSDBG("temp_hsync = %d , temp_vsync = %d"
>> +                               "timing_hsync = %d, timing_vsync = %d\n",
>> +                               temp_hsync, temp_hsync,
>> +                               timing_hsync, timing_vsync);
>> +
>> +                       if ((temp_hsync == timing_hsync) &&
>> +                                       (temp_vsync == timing_vsync)) {
>> +                               code = i;
>> +                               cm.code = code_index[i];
>> +                               if (code < 14)
>> +                                       cm.mode = HDMI_HDMI;
>> +                               else
>> +                                       cm.mode = HDMI_DVI;
>> +                               DSSINFO("Hdmi_code = %d mode = %d\n",
>> +                                        cm.code, cm.mode);
>> +                               print_omap_video_timings(&temp);
>> +                               break;
>> +                        }
>> +               }
>> +       }
>> +
>> +       return cm;
>> +}
>> +
>> +void get_horz_vert_timing_info(int current_descriptor_addrs, u8 *edid ,
>> +               struct omap_video_timings *timings)
>> +{
>> +       /* X and Y resolution */
>> +       timings->x_res = (((edid[current_descriptor_addrs + 4] & 0xF0) << 4) |
>> +                        edid[current_descriptor_addrs + 2]);
>> +       timings->y_res = (((edid[current_descriptor_addrs + 7] & 0xF0) << 4) |
>> +                        edid[current_descriptor_addrs + 5]);
>> +
>> +       timings->pixel_clock = ((edid[current_descriptor_addrs + 1] << 8) |
>> +                               edid[current_descriptor_addrs]);
>> +
>> +       timings->pixel_clock = 10 * timings->pixel_clock;
>> +
>> +       /* HORIZONTAL FRONT PORCH */
>> +       timings->hfp = edid[current_descriptor_addrs + 8] |
>> +                       ((edid[current_descriptor_addrs + 11] & 0xc0) << 2);
>> +       /* HORIZONTAL SYNC WIDTH */
>> +       timings->hsw = edid[current_descriptor_addrs + 9] |
>> +                       ((edid[current_descriptor_addrs + 11] & 0x30) << 4);
>> +       /* HORIZONTAL BACK PORCH */
>> +       timings->hbp = (((edid[current_descriptor_addrs + 4] & 0x0F) << 8) |
>> +                       edid[current_descriptor_addrs + 3]) -
>> +                       (timings->hfp + timings->hsw);
>> +       /* VERTICAL FRONT PORCH */
>> +       timings->vfp = ((edid[current_descriptor_addrs + 10] & 0xF0) >> 4) |
>> +                       ((edid[current_descriptor_addrs + 11] & 0x0f) << 2);
>> +       /* VERTICAL SYNC WIDTH */
>> +       timings->vsw = (edid[current_descriptor_addrs + 10] & 0x0F) |
>> +                       ((edid[current_descriptor_addrs + 11] & 0x03) << 4);
>> +       /* VERTICAL BACK PORCH */
>> +       timings->vbp = (((edid[current_descriptor_addrs + 7] & 0x0F) << 8) |
>> +                       edid[current_descriptor_addrs + 6]) -
>> +                       (timings->vfp + timings->vsw);
>> +
>> +       print_omap_video_timings(timings);
>> +
>> +}
>> +
>> +/* Description : This function gets the resolution information from EDID */
>> +static void get_edid_timing_data(u8 *edid)
>> +{
>> +       u8 count, code;
>> +       u16 current_descriptor_addrs;
>> +       struct hdmi_cm cm;
>> +
>> +       /* seach block 0, there are 4 DTDs arranged in priority order */
>> +       for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) {
>> +               current_descriptor_addrs =
>> +                       EDID_DESCRIPTOR_BLOCK0_ADDRESS +
>> +                       count * EDID_TIMING_DESCRIPTOR_SIZE;
>> +               get_horz_vert_timing_info(current_descriptor_addrs,
>> +                               edid, &edid_timings);
>> +               cm = hdmi_get_code(&edid_timings);
>> +               DSSINFO("Block0[%d] value matches code = %d , mode = %d\n",
>> +                       count, cm.code, cm.mode);
>> +               if (cm.code == -1) {
>> +                       continue;
>> +               } else {
>> +                       hdmi.code = cm.code;
>> +                       hdmi.mode = cm.mode;
>> +                       DSSINFO("code = %d , mode = %d\n",
>> +                               hdmi.code, hdmi.mode);
>> +                       return;
>> +               }
>> +       }
>> +       if (edid[0x7e] != 0x00) {
>> +               for (count = 0; count < EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR;
>> +                       count++) {
>> +                       current_descriptor_addrs =
>> +                       EDID_DESCRIPTOR_BLOCK1_ADDRESS +
>> +                       count * EDID_TIMING_DESCRIPTOR_SIZE;
>> +                       get_horz_vert_timing_info(current_descriptor_addrs,
>> +                                               edid, &edid_timings);
>> +                       cm = hdmi_get_code(&edid_timings);
>> +                       DSSINFO("Block1[%d] value matches code = %d, mode = %d",
>> +                               count, cm.code, cm.mode);
>> +                       if (cm.code == -1) {
>> +                               continue;
>> +                       } else {
>> +                               hdmi.code = cm.code;
>> +                               hdmi.mode = cm.mode;
>> +                               DSSINFO("code = %d , mode = %d\n",
>> +                                       hdmi.code, hdmi.mode);
>> +                               return;
>> +                       }
>> +               }
>> +       }
>> +
>> +       DSSINFO("no valid timing found , falling back to VGA\n");
>> +       hdmi.code = 4; /* setting default value of 640 480 VGA */
>> +       hdmi.mode = HDMI_DVI;
>> +       code = code_vesa[hdmi.code];
>> +       edid_timings = cea_vesa_timings[code].timings;
>> +}
>> +
>> +static int hdmi_read_edid(struct omap_video_timings *dp)
>> +{
>> +       int ret = 0, code;
>> +
>> +       memset(edid, 0, HDMI_EDID_MAX_LENGTH);
>> +
>> +       if (!edid_set)
>> +               ret = read_edid(edid, HDMI_EDID_MAX_LENGTH);
>> +
>> +       if (ret != 0) {
>> +               DSSWARN("failed to read E-EDID\n");
>> +       } else {
>> +               if (!memcmp(edid, header, sizeof(header))) {
>> +                       /* search for timings of default resolution */
>> +                       get_edid_timing_data(edid);
>> +                       edid_set = true;
>> +               }
>> +       }
>> +
>> +       if (!edid_set) {
>> +               DSSINFO("fallback to VGA\n");
>> +               hdmi.code = 4; /* setting default value of 640 480 VGA */
>> +               hdmi.mode = HDMI_DVI;
>> +       }
>> +
>> +       code = get_timings_index();
>> +
>> +       *dp = cea_vesa_timings[code].timings;
>> +
>> +       DSSDBG("print EDID timings\n");
>> +       print_omap_video_timings(dp);
>> +
>> +       return 0;
>> +}
>> +
>> +static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
>> +                       struct hdmi_core_infoframe_avi *avi_cfg,
>> +                       struct hdmi_core_packet_enable_repeat *repeat_cfg)
>> +{
>> +       DSSDBG("Enter hdmi_core_init\n");
>> +
>> +       /* video core */
>> +       video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
>> +       video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT;
>> +       video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE;
>> +       video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
>> +       video_cfg->hdmi_dvi = HDMI_DVI;
>> +       video_cfg->tclk_sel_clkmult = FPLL10IDCK;
>> +
>> +       /* info frame */
>> +       avi_cfg->db1_format = 0;
>> +       avi_cfg->db1_active_info = 0;
>> +       avi_cfg->db1_bar_info_dv = 0;
>> +       avi_cfg->db1_scan_info = 0;
>> +       avi_cfg->db2_colorimetry = 0;
>> +       avi_cfg->db2_aspect_ratio = 0;
>> +       avi_cfg->db2_active_fmt_ar = 0;
>> +       avi_cfg->db3_itc = 0;
>> +       avi_cfg->db3_ec = 0;
>> +       avi_cfg->db3_q_range = 0;
>> +       avi_cfg->db3_nup_scaling = 0;
>> +       avi_cfg->db4_videocode = 0;
>> +       avi_cfg->db5_pixel_repeat = 0;
>> +       avi_cfg->db6_7_line_eoftop = 0 ;
>> +       avi_cfg->db8_9_line_sofbottom = 0;
>> +       avi_cfg->db10_11_pixel_eofleft = 0;
>> +       avi_cfg->db12_13_pixel_sofright = 0;
>> +
>> +       /* packet enable and repeat */
>> +       repeat_cfg->audio_pkt = 0;
>> +       repeat_cfg->audio_pkt_repeat = 0;
>> +       repeat_cfg->avi_infoframe = 0;
>> +       repeat_cfg->avi_infoframe_repeat = 0;
>> +       repeat_cfg->gen_cntrl_pkt = 0;
>> +       repeat_cfg->gen_cntrl_pkt_repeat = 0;
>> +       repeat_cfg->generic_pkt = 0;
>> +       repeat_cfg->generic_pkt_repeat = 0;
>> +}
>> +
>> +static void hdmi_core_powerdown_disable(void)
>> +{
>> +       DSSDBG("Enter hdmi_core_powerdown_disable\n");
>> +       REG_FLD_MOD(HDMI_CORE_CTRL1, 0x0, 0, 0);
>> +}
>> +
>> +static void hdmi_core_swreset_release(void)
>> +{
>> +       DSSDBG("Enter hdmi_core_swreset_release\n");
>> +       REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x0, 0, 0);
>> +}
>> +
>> +static void hdmi_core_swreset_assert(void)
>> +{
>> +       DSSDBG("Enter hdmi_core_swreset_assert\n");
>> +       REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x1, 0, 0);
>> +}
>> +
>> +/* DSS_HDMI_CORE_VIDEO_CONFIG */
>> +static void hdmi_core_video_config(struct hdmi_core_video_config *cfg)
>> +{
>> +       u32 r = 0;
>> +
>> +       /* sys_ctrl1 default configuration not tunable */
>> +       r = hdmi_read_reg(HDMI_CORE_CTRL1);
>> +       r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5);
>> +       r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4);
>> +       r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2);
>> +       r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1);
>> +       hdmi_write_reg(HDMI_CORE_CTRL1, r);
>> +
>> +       REG_FLD_MOD(HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6);
>> +
>> +       /* Vid_Mode */
>> +       r = hdmi_read_reg(HDMI_CORE_SYS_VID_MODE);
>> +
>> +       /* dither truncation configuration */
>> +       if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) {
>> +               r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6);
>> +               r = FLD_MOD(r, 1, 5, 5);
>> +       } else {
>> +               r = FLD_MOD(r, cfg->op_dither_truc, 7, 6);
>> +               r = FLD_MOD(r, 0, 5, 5);
>> +       }
>> +       hdmi_write_reg(HDMI_CORE_SYS_VID_MODE, r);
>> +
>> +       /* HDMI_Ctrl */
>> +       r = hdmi_read_reg(HDMI_CORE_AV_HDMI_CTRL);
>> +       r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);
>> +       r = FLD_MOD(r, cfg->pkt_mode, 5, 3);
>> +       r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0);
>> +       hdmi_write_reg(HDMI_CORE_AV_HDMI_CTRL, r);
>> +
>> +       /* TMDS_CTRL */
>> +       REG_FLD_MOD(HDMI_CORE_SYS_TMDS_CTRL,
>> +               cfg->tclk_sel_clkmult, 6, 5);
>> +}
>> +
>> +static void hdmi_core_aux_infoframe_avi_config(
>> +               struct hdmi_core_infoframe_avi info_avi)
>> +{
>> +       u32 val;
>> +       char sum = 0, checksum = 0;
>> +
>> +       sum += 0x82 + 0x002 + 0x00D;
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_TYPE, 0x082);
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_VERS, 0x002);
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_LEN, 0x00D);
>> +
>> +       val = (info_avi.db1_format << 5) |
>> +               (info_avi.db1_active_info << 4) |
>> +               (info_avi.db1_bar_info_dv << 2) |
>> +               (info_avi.db1_scan_info);
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(0), val);
>> +       sum += val;
>> +
>> +       val = (info_avi.db2_colorimetry << 6) |
>> +               (info_avi.db2_aspect_ratio << 4) |
>> +               (info_avi.db2_active_fmt_ar);
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(1), val);
>> +       sum += val;
>> +
>> +       val = (info_avi.db3_itc << 7) |
>> +               (info_avi.db3_ec << 4) |
>> +               (info_avi.db3_q_range << 2) |
>> +               (info_avi.db3_nup_scaling);
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(2), val);
>> +       sum += val;
>> +
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(3), info_avi.db4_videocode);
>> +       sum += info_avi.db4_videocode;
>> +
>> +       val = info_avi.db5_pixel_repeat;
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(4), val);
>> +       sum += val;
>> +
>> +       val = info_avi.db6_7_line_eoftop & 0x00FF;
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(5), val);
>> +       sum += val;
>> +
>> +       val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(6), val);
>> +       sum += val;
>> +
>> +       val = info_avi.db8_9_line_sofbottom & 0x00FF;
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(7), val);
>> +       sum += val;
>> +
>> +       val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(8), val);
>> +       sum += val;
>> +
>> +       val = info_avi.db10_11_pixel_eofleft & 0x00FF;
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(9), val);
>> +       sum += val;
>> +
>> +       val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(10), val);
>> +       sum += val;
>> +
>> +       val = info_avi.db12_13_pixel_sofright & 0x00FF;
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(11), val);
>> +       sum += val;
>> +
>> +       val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(12), val);
>> +       sum += val;
>> +
>> +       checksum = 0x100 - sum;
>> +       hdmi_write_reg(HDMI_CORE_AV_AVI_CHSUM, checksum);
>> +}
>> +
>> +static void hdmi_core_av_packet_config(
>> +               struct hdmi_core_packet_enable_repeat repeat_cfg)
>> +{
>> +       /* enable/repeat the infoframe */
>> +       hdmi_write_reg(HDMI_CORE_AV_PB_CTRL1,
>> +               (repeat_cfg.audio_pkt << 5)|
>> +               (repeat_cfg.audio_pkt_repeat << 4)|
>> +               (repeat_cfg.avi_infoframe << 1)|
>> +               (repeat_cfg.avi_infoframe_repeat));
>> +
>> +       /* enable/repeat the packet */
>> +       hdmi_write_reg(HDMI_CORE_AV_PB_CTRL2,
>> +               (repeat_cfg.gen_cntrl_pkt << 3)|
>> +               (repeat_cfg.gen_cntrl_pkt_repeat << 2)|
>> +               (repeat_cfg.generic_pkt << 1)|
>> +               (repeat_cfg.generic_pkt_repeat));
>> +}
>> +
>> +static void hdmi_wp_init(struct hdmi_video_timing *timings,
>> +                       struct hdmi_video_format *video_fmt,
>> +                       struct hdmi_video_interface *video_int)
>> +{
>> +       DSSDBG("Enter hdmi_wp_init\n");
>> +
>> +       timings->hbp = 0;
>> +       timings->hfp = 0;
>> +       timings->hsw = 0;
>> +       timings->vbp = 0;
>> +       timings->vfp = 0;
>> +       timings->vsw = 0;
>> +
>> +       video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
>> +       video_fmt->y_res = 0;
>> +       video_fmt->x_res = 0;
>> +
>> +       video_int->vsp = 0;
>> +       video_int->hsp = 0;
>> +
>> +       video_int->interlacing = 0;
>> +       video_int->tm = 0; /* HDMI_TIMING_SLAVE */
>> +
>> +}
>> +
>> +/* PHY_PWR_CMD */
>> +int hdmi_wait_phy_pwr(int val)
>> +{
>> +       REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 7, 6);
>> +
>> +       if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 5, 4, val) != val) {
>> +               DSSERR("Failed to set PHY power mode to %d\n", val);
>> +               return -ENODEV;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +/* PLL_PWR_CMD */
>> +int hdmi_wait_pll_pwr(int val)
>> +{
>> +       REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 3, 2);
>> +
>> +       /* wait till PHY_PWR_STATUS=ON */
>> +       if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 1, 0, val) != val) {
>> +               DSSERR("Failed to set PHY_PWR_STATUS to ON\n");
>> +               return -ENODEV;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +void hdmi_wp_video_stop(void)
>> +{
>> +       REG_FLD_MOD(HDMI_WP_VIDEO_CFG, 0, 31, 31);
>> +}
>> +
>> +void hdmi_wp_video_start(void)
>> +{
>> +       REG_FLD_MOD(HDMI_WP_VIDEO_CFG, (u32)0x1, 31, 31);
>> +}
>> +
>> +static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt,
>> +       struct hdmi_video_timing *timings, struct hdmi_config *param)
>> +{
>> +       DSSDBG("Enter hdmi_wp_video_init_format\n");
>> +
>> +       video_fmt->y_res = param->lpp;
>> +       video_fmt->x_res = param->ppl;
>> +
>> +       timings->hbp = param->hbp;
>> +       timings->hfp = param->hfp;
>> +       timings->hsw = param->hsw;
>> +       timings->vbp = param->vbp;
>> +       timings->vfp = param->vfp;
>> +       timings->vsw = param->vsw;
>> +}
>> +
>> +static void hdmi_wp_video_config_format(
>> +               struct hdmi_video_format *video_fmt)
>> +{
>> +       u32 l = 0;
>> +
>> +       REG_FLD_MOD(HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, 10, 8);
>> +
>> +       l |= FLD_VAL(video_fmt->y_res, 31, 16);
>> +       l |= FLD_VAL(video_fmt->x_res, 15, 0);
>> +       hdmi_write_reg(HDMI_WP_VIDEO_SIZE, l);
>> +}
>> +
>> +static void hdmi_wp_video_config_interface(
>> +               struct hdmi_video_interface *video_int)
>> +{
>> +       u32 r;
>> +       DSSDBG("Enter hdmi_wp_video_config_interface\n");
>> +
>> +       r = hdmi_read_reg(HDMI_WP_VIDEO_CFG);
>> +       r = FLD_MOD(r, video_int->vsp, 7, 7);
>> +       r = FLD_MOD(r, video_int->hsp, 6, 6);
>> +       r = FLD_MOD(r, video_int->interlacing, 3, 3);
>> +       r = FLD_MOD(r, video_int->tm, 1, 0);
>> +       hdmi_write_reg(HDMI_WP_VIDEO_CFG, r);
>> +}
>> +
>> +static void hdmi_wp_video_config_timing(
>> +               struct hdmi_video_timing *timings)
>> +{
>> +       u32 timing_h = 0;
>> +       u32 timing_v = 0;
>> +
>> +       DSSDBG("Enter hdmi_wp_video_config_timing\n");
>> +
>> +       timing_h |= FLD_VAL(timings->hbp, 31, 20);
>> +       timing_h |= FLD_VAL(timings->hfp, 19, 8);
>> +       timing_h |= FLD_VAL(timings->hsw, 7, 0);
>> +       hdmi_write_reg(HDMI_WP_VIDEO_TIMING_H, timing_h);
>> +
>> +       timing_v |= FLD_VAL(timings->vbp, 31, 20);
>> +       timing_v |= FLD_VAL(timings->vfp, 19, 8);
>> +       timing_v |= FLD_VAL(timings->vsw, 7, 0);
>> +       hdmi_write_reg(HDMI_WP_VIDEO_TIMING_V, timing_v);
>> +}
>> +
>> +void hdmi_lib_enable(struct hdmi_config *cfg)
>> +{
>
> There is no library here.
>
>> +       /* HDMI */
>> +       struct hdmi_video_timing video_timing;
>> +       struct hdmi_video_format video_format;
>> +       struct hdmi_video_interface video_interface;
>> +       /* HDMI core */
>> +       struct hdmi_core_infoframe_avi avi_cfg;
>> +       struct hdmi_core_video_config v_core_cfg;
>> +       struct hdmi_core_packet_enable_repeat repeat_cfg;
>> +
>> +       hdmi_wp_init(&video_timing, &video_format,
>> +               &video_interface);
>> +
>> +       hdmi_core_init(&v_core_cfg,
>> +               &avi_cfg,
>> +               &repeat_cfg);
>> +
>> +       /* init DSS register */
>> +       hdmi_wp_video_init_format(&video_format,
>> +                       &video_timing, cfg);
>> +
>> +       hdmi_wp_video_config_timing(&video_timing);
>> +
>> +       /* video config */
>> +       video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422;
>> +
>> +       hdmi_wp_video_config_format(&video_format);
>> +
>> +       video_interface.vsp = cfg->v_pol;
>> +       video_interface.hsp = cfg->h_pol;
>> +       video_interface.interlacing = cfg->interlace;
>> +       video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */
>> +
>> +       hdmi_wp_video_config_interface(&video_interface);
>> +
>> +       /*
>> +        * configure core video part
>> +        * set software reset in the core
>> +        */
>> +       hdmi_core_swreset_assert();
>> +
>> +       /* power down off */
>> +       hdmi_core_powerdown_disable();
>> +
>> +       v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
>> +       v_core_cfg.hdmi_dvi = cfg->hdmi_dvi;
>> +
>> +       hdmi_core_video_config(&v_core_cfg);
>> +
>> +       /* release software reset in the core */
>> +       hdmi_core_swreset_release();
>> +
>> +       /*
>> +        * configure packet
>> +        * info frame video see doc CEA861-D page 65
>> +        */
>> +       avi_cfg.db1_format = INFOFRAME_AVI_DB1Y_RGB;
>> +       avi_cfg.db1_active_info =
>> +               INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
>> +       avi_cfg.db1_bar_info_dv = INFOFRAME_AVI_DB1B_NO;
>> +       avi_cfg.db1_scan_info = INFOFRAME_AVI_DB1S_0;
>> +       avi_cfg.db2_colorimetry = INFOFRAME_AVI_DB2C_NO;
>> +       avi_cfg.db2_aspect_ratio = INFOFRAME_AVI_DB2M_NO;
>> +       avi_cfg.db2_active_fmt_ar = INFOFRAME_AVI_DB2R_SAME;
>> +       avi_cfg.db3_itc = INFOFRAME_AVI_DB3ITC_NO;
>> +       avi_cfg.db3_ec = INFOFRAME_AVI_DB3EC_XVYUV601;
>> +       avi_cfg.db3_q_range = INFOFRAME_AVI_DB3Q_DEFAULT;
>> +       avi_cfg.db3_nup_scaling = INFOFRAME_AVI_DB3SC_NO;
>> +       avi_cfg.db4_videocode = cfg->video_format;
>> +       avi_cfg.db5_pixel_repeat = INFOFRAME_AVI_DB5PR_NO;
>> +       avi_cfg.db6_7_line_eoftop = 0;
>> +       avi_cfg.db8_9_line_sofbottom = 0;
>> +       avi_cfg.db10_11_pixel_eofleft = 0;
>> +       avi_cfg.db12_13_pixel_sofright = 0;
>> +
>> +       hdmi_core_aux_infoframe_avi_config(avi_cfg);
>> +
>> +       /* enable/repeat the infoframe */
>> +       repeat_cfg.avi_infoframe = PACKETENABLE;
>> +       repeat_cfg.avi_infoframe_repeat = PACKETREPEATON;
>> +
>> +       /* wakeup */
>> +       repeat_cfg.audio_pkt = PACKETENABLE;
>> +       repeat_cfg.audio_pkt_repeat = PACKETREPEATON;
>> +       hdmi_core_av_packet_config(repeat_cfg);
>> +}
>> +
>> +static void update_hdmi_timings(struct hdmi_config *cfg,
>> +               struct omap_video_timings *timings, int code)
>> +{
>> +       cfg->ppl = timings->x_res;
>> +       cfg->lpp = timings->y_res;
>> +       cfg->hbp = timings->hbp;
>> +       cfg->hfp = timings->hfp;
>> +       cfg->hsw = timings->hsw;
>> +       cfg->vbp = timings->vbp;
>> +       cfg->vfp = timings->vfp;
>> +       cfg->vsw = timings->vsw;
>> +       cfg->pixel_clock = timings->pixel_clock;
>> +       cfg->v_pol = cea_vesa_timings[code].vsync_pol;
>> +       cfg->h_pol = cea_vesa_timings[code].hsync_pol;
>> +}
>> +
>> +void hdmi_lib_exit(void)
>> +{
>> +
>> +}
>> +
>> +int hdmi_wait_softreset(void)
>> +{
>> +       /* reset W1 */
>> +       REG_FLD_MOD(HDMI_WP_SYSCONFIG, 0x1, 0, 0);
>> +
>> +       /* wait till SOFTRESET == 0 */
>> +       if (hdmi_wait_for_bit_change(HDMI_WP_SYSCONFIG, 0, 0, 0) != 0) {
>> +               DSSERR("sysconfig reset failed\n");
>> +               return -ENODEV;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +void hdmi_compute_pll(unsigned long clkin, int phy,
>> +       int n, struct hdmi_pll_info *pi)
>> +{
>> +       unsigned long refclk;
>> +       u32 mf;
>> +
>> +       /*
>> +        * Input clock is predivided by N + 1
>> +        * out put of which is reference clk
>> +        */
>> +       refclk = clkin / (n + 1);
>> +       pi->regn = n;
>> +
>> +       /*
>> +        * multiplier is pixel_clk/ref_clk
>> +        * Multiplying by 100 to avoid fractional part removal
>> +        */
>> +       pi->regm = (phy * 100/(refclk))/100;
>> +       pi->regm2 = 1;
>> +
>> +       /*
>> +        * fractional multiplier is remainder of the difference between
>> +        * multiplier and actual phy(required pixel clock thus should be
>> +        * multiplied by 2^18(262144) divided by the reference clock
>> +        */
>> +       mf = (phy - pi->regm * refclk) * 262144;
>> +       pi->regmf = mf/(refclk);
>> +
>> +       /*
>> +        * Dcofreq should be set to 1 if required pixel clock
>> +        * is greater than 1000MHz
>> +        */
>> +       pi->dcofreq = phy > 1000 * 100;
>> +       pi->regsd = ((pi->regm * clkin / 10) / ((n + 1) * 250) + 5) / 10;
>> +
>> +       DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
>> +       DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
>> +}
>> +
>> +static void hdmi_enable_clocks(int enable)
>> +{
>> +       if (enable)
>> +               dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK |
>> +                               DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
>> +       else
>> +               dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK |
>> +                               DSS_CLK_SYSCK | DSS_CLK_VIDFCK);
>> +}
>> +
>> +static int hdmi_power_on(struct omap_dss_device *dssdev)
>> +{
>> +       int r, code = 0;
>> +       struct hdmi_pll_info pll_data;
>> +       struct omap_video_timings *p;
>> +       int clkin, n, phy;
>> +
>> +       hdmi_enable_clocks(1);
>> +
>> +       dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
>> +
>> +       p = &dssdev->panel.timings;
>> +
>> +       DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
>> +               dssdev->panel.timings.x_res,
>> +               dssdev->panel.timings.y_res);
>> +
>> +       DSSDBG("Read EDID as no EDID is not set on poweron\n");
>> +       r = hdmi_read_edid(p);
>> +       if (r)
>> +               return -EIO;
>> +
>> +       code = get_timings_index();
>> +       dssdev->panel.timings = cea_vesa_timings[code].timings;
>> +       update_hdmi_timings(&hdmi.cfg, p, code);
>> +
>> +       clkin = 3840; /* 38.4 MHz */
>> +       n = 15; /* this is a constant for our math */
>> +       phy = p->pixel_clock;
>> +
>> +       hdmi_compute_pll(clkin, phy, n, &pll_data);
>> +
>> +       hdmi_wp_video_stop();
>> +
>> +       /* config the PLL and PHY first */
>> +       r = hdmi_pll_program(&pll_data);
>> +       if (r) {
>> +               DSSDBG("Failed to lock PLL\n");
>> +               return -EIO;
>> +       }
>> +
>> +       r = hdmi_phy_init();
>> +       if (r) {
>> +               DSSDBG("Failed to start PHY\n");
>> +               return -EIO;
>> +       }
>> +
>> +       hdmi.cfg.hdmi_dvi = hdmi.mode;
>> +       hdmi.cfg.video_format = hdmi.code;
>> +       hdmi_lib_enable(&hdmi.cfg);
>> +
>> +       /* these settings are independent of overlays */
>> +       dss_select_hdmi_venc(1);
>> +
>> +       /* bypass TV gamma table */
>> +       dispc_enable_gamma_table(0);
>> +
>> +       /* tv size */
>> +       dispc_set_digit_size(dssdev->panel.timings.x_res,
>> +                       dssdev->panel.timings.y_res);
>> +
>> +       dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 1);
>> +
>> +       hdmi_wp_video_start();
>> +
>> +       return 0;
>> +}
>> +
>> +static void hdmi_power_off(struct omap_dss_device *dssdev)
>> +{
>> +       dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0);
>> +
>> +       hdmi_wp_video_stop();
>> +       hdmi_phy_off();
>> +       hdmi_wait_pll_pwr(HDMI_PLLPWRCMD_ALLOFF);
>> +       hdmi_enable_clocks(0);
>> +
>> +       edid_set = 0;
>> +}
>> +
>> +int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
>> +{
>> +       int r = 0;
>> +
>> +       DSSDBG("ENTER hdmi_display_enable\n");
>> +
>> +       mutex_lock(&hdmi.lock);
>> +
>> +       r = omap_dss_start_device(dssdev);
>> +       if (r) {
>> +               DSSDBG("failed to start device\n");
>> +               goto err;
>> +       }
>> +
>> +       if (dssdev->platform_enable)
>> +               dssdev->platform_enable(dssdev);
>> +
>> +       r = hdmi_power_on(dssdev);
>> +       if (r) {
>> +               DSSERR("failed to power on device\n");
>> +               goto err;
>> +       }
>> +
>> +err:
>> +       mutex_unlock(&hdmi.lock);
>
> The error handling here needs to handle omap_dss_start_device and
> platform_enable.
ok.
>
>> +
>> +       return r;
>> +}
>> +
>> +void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
>> +{
>> +       DSSDBG("Enter hdmi_display_disable\n");
>> +
>> +       mutex_lock(&hdmi.lock);
>> +
>> +       omap_dss_stop_device(dssdev);
>> +
>> +       if (dssdev->platform_disable)
>> +               dssdev->platform_disable(dssdev);
>> +
>> +       hdmi_power_off(dssdev);
>> +
>
> You should do the disabling in reverse order compared to enabling.
>
>> +       mutex_unlock(&hdmi.lock);
>> +}
>> +
>> +int omapdss_hdmi_display_suspend(struct omap_dss_device *dssdev)
>> +{
>> +       DSSDBG("hdmi_display_suspend\n");
>> +
>> +       mutex_lock(&hdmi.lock);
>> +
>> +       omap_dss_stop_device(dssdev);
>> +
>> +       hdmi_power_off(dssdev);
>> +
>> +       mutex_unlock(&hdmi.lock);
>> +
>> +       return 0;
>> +}
>
> The code in suspend and resume do not match. And what is the need for
> suspend and resume? They are the same as disable and enable.
>
sorry i was carried over by calling corresponding function from panel
driver ,I could reuse
enable and disable functions in hdmi.c for suspend and resume.

>  Tomi
>
Thanks and regards,
Mythri.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 6/8] OMAP4 : DSS2 : HDMI: HDMI panel driver addition in the DSS
  2011-02-27  9:43   ` Tomi Valkeinen
@ 2011-02-28  6:14     ` K, Mythri P
  0 siblings, 0 replies; 23+ messages in thread
From: K, Mythri P @ 2011-02-28  6:14 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap@vger.kernel.org

Hi Tomi,
I shall add per device lock and make the lock consistent , as audio
can also call these functions.

Thanks and regards,
Mythri.

On Sun, Feb 27, 2011 at 3:13 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Fri, 2011-02-25 at 08:21 -0600, K, Mythri P wrote:
>> The panel driver(hdmi_omap4_panel.c) in dss file acts as a controller
>> to manage the enable and disable requests and synchronize audio and video.
>> Also the header file to export the hdmi registers is added in the
>> plat-omap , so that it can be accessed by audio driver.
>>
>> Signed-off-by: Mythri P K <mythripk@ti.com>
>> ---
>>  drivers/video/omap2/dss/Kconfig            |    8 ++
>>  drivers/video/omap2/dss/Makefile           |    1 +
>>  drivers/video/omap2/dss/hdmi_omap4_panel.c |  190 ++++++++++++++++++++++++++++
>>  3 files changed, 199 insertions(+), 0 deletions(-)
>>  create mode 100644 drivers/video/omap2/dss/hdmi_omap4_panel.c
>>
>> diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
>> index fe1ab09..670a55d 100644
>> --- a/drivers/video/omap2/dss/Kconfig
>> +++ b/drivers/video/omap2/dss/Kconfig
>> @@ -125,4 +125,12 @@ config OMAP2_DSS_MIN_FCK_PER_PCK
>>         Max FCK is 173MHz, so this doesn't work if your PCK
>>         is very high.
>>
>> +config OMAP4_PANEL_HDMI
>> +     bool "HDMI panel support"
>> +     depends on OMAP2_DSS_HDMI
>> +        default n
>> +     help
>> +       HDMI panel. This adds the High Definition Multimedia panel.
>> +       See http://www.hdmi.org/ for HDMI specification.
>> +
>>  endif
>> diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
>> index 5998b69..95234d4 100644
>> --- a/drivers/video/omap2/dss/Makefile
>> +++ b/drivers/video/omap2/dss/Makefile
>> @@ -6,3 +6,4 @@ omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
>>  omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
>>  omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
>>  omapdss-$(CONFIG_OMAP2_DSS_HDMI) += hdmi.o
>> +obj-$(CONFIG_OMAP4_PANEL_HDMI) += hdmi_omap4_panel.o
>> diff --git a/drivers/video/omap2/dss/hdmi_omap4_panel.c b/drivers/video/omap2/dss/hdmi_omap4_panel.c
>> new file mode 100644
>> index 0000000..c28b1f6
>> --- /dev/null
>> +++ b/drivers/video/omap2/dss/hdmi_omap4_panel.c
>> @@ -0,0 +1,190 @@
>> +/*
>> + * hdmi_omap4_panel.c
>> + *
>> + * HDMI library support functions for TI OMAP4 processors.
>> + *
>> + * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
>> + * Authors:  MythriPk <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"
>
> This is not used.
>
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/err.h>
>> +#include <linux/io.h>
>> +#include <linux/mutex.h>
>> +#include <linux/string.h>
>> +#include <linux/delay.h>
>> +#include <linux/module.h>
>> +#include <linux/seq_file.h>
>> +#include <plat/display.h>
>
> Most of these includes are not needed.
>
>> +
>> +#include "dss.h"
>> +
>> +static struct {
>> +     struct mutex hdmi_lock;
>> +} hdmi;
>
> Static variables in panel drivers are not good, as they won't work if
> there are two devices which use the same driver. In this case that
> cannot happen, as there's only one HDMI module in DSS. However, it's
> worth to mention here in a comment. Or, do it properly and create a per
> device data structure.
>
>> +
>> +
>> +static int hdmi_panel_probe(struct omap_dss_device *dssdev)
>> +{
>> +     DSSDBG("ENTER hdmi_panel_probe\n");
>> +
>> +     dssdev->panel.config = OMAP_DSS_LCD_TFT |
>> +                     OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS;
>> +
>> +     /*
>> +      * Initialize the timings to 1920 * 1080
>> +      * This is only for framebuffer update not for TV timing setting
>> +      * Setting TV timing will be done only on enable
>> +      */
>> +     dssdev->panel.timings.x_res = 1920;
>> +     dssdev->panel.timings.y_res = 1080;
>> +
>> +     DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
>> +             dssdev->panel.timings.x_res,
>> +             dssdev->panel.timings.y_res);
>> +     return 0;
>> +}
>> +
>> +static void hdmi_panel_remove(struct omap_dss_device *dssdev)
>> +{
>> +
>> +}
>> +
>> +static int hdmi_panel_enable(struct omap_dss_device *dssdev)
>> +{
>> +     int r = 0;
>> +     DSSDBG("ENTER hdmi_panel_enable\n");
>> +
>> +     if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)
>> +             return -EINVAL;
>> +
>> +     mutex_lock(&hdmi.hdmi_lock);
>
> I commented about this in earlier mails already. You need to use the
> locks consistently and have the dssdev->state reads also inside the
> lock.
>
> Think what happens if, say, two threads call hdmi_panel_enable at the
> same time.
>
>  Tomi
>
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 3/8] OMAP4 : DSS : HDMI: HDMI specific display controller and dss change.
  2011-02-27  9:23   ` Tomi Valkeinen
@ 2011-02-28  6:21     ` K, Mythri P
  2011-02-28  6:42       ` Tomi Valkeinen
  0 siblings, 1 reply; 23+ messages in thread
From: K, Mythri P @ 2011-02-28  6:21 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap@vger.kernel.org

Hi Tomi,

On Sun, Feb 27, 2011 at 2:53 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Fri, 2011-02-25 at 08:21 -0600, K, Mythri P wrote:
>> Adding changes to set gamma table bit for TV interface and function to select
>> between VENC and HDMI.
>>
>> Signed-off-by: Mythri P K <mythripk@ti.com>
>> ---
>>  drivers/video/omap2/dss/dispc.c |    5 +++++
>>  drivers/video/omap2/dss/dss.c   |    7 +++++++
>>  drivers/video/omap2/dss/dss.h   |    2 ++
>>  3 files changed, 14 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
>> index 6d9bb17..16f1106 100644
>> --- a/drivers/video/omap2/dss/dispc.c
>> +++ b/drivers/video/omap2/dss/dispc.c
>> @@ -1213,6 +1213,11 @@ void dispc_enable_zorder(enum omap_plane plane, bool enable)
>>       dispc_write_reg(dispc_reg_att[plane], val);
>>  }
>>
>> +void dispc_enable_gamma_table(bool enable)
>> +{
>> +     REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
>> +}
>> +
>>  static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
>>  {
>>       u32 val;
>> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
>> index 99de4e1..127d42e 100644
>> --- a/drivers/video/omap2/dss/dss.c
>> +++ b/drivers/video/omap2/dss/dss.c
>> @@ -559,6 +559,13 @@ void dss_set_dac_pwrdn_bgz(bool enable)
>>       REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
>>  }
>>
>> +void dss_select_hdmi_venc(bool hdmi)
>> +{
>> +     REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* 0x1 for HDMI, 0x0 VENC */
>> +     if (hdmi)
>> +             REG_FLD_MOD(DSS_CONTROL, 0, 9, 8);
>> +}
>
> bool argument for this function is very confusing. Which one is true?
> Perhaps this could use an enum.
I have added a comment , 1 is for HDMI and 0 for VENC.
>
> I've tried to keep the habit of having the name of the register field in
> comments to make the code easier to read. For example, /*
> VENC_HDMI_SWITCH */ for the bit 15.
I can add this.
>
> The bits 8 and 9 are FCK_CLK_SWITCH. Why do you set it here? Looks
> rather dangerous to change the clock source like that.
>
This is to select what would be the clock source to DISPC, HDMI would
need the DISPC
to run at the rate of pixel clock (TMDS if deep color is set ) required by HDMI.
Where as DSI does not have any such constraint( correct me if i am wrong).
I suppose we can have a patch to select the correct clock source to
DISPC dynamically
based on what panels are connected later on ?

>  Tomi
>
>
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 5/8] OMAP4 : DSS2 : HDMI: HDMI driver addition in the DSS drivers interface
  2011-02-28  6:11     ` K, Mythri P
@ 2011-02-28  6:27       ` Tomi Valkeinen
  2011-02-28  6:30         ` K, Mythri P
  0 siblings, 1 reply; 23+ messages in thread
From: Tomi Valkeinen @ 2011-02-28  6:27 UTC (permalink / raw)
  To: K, Mythri P; +Cc: linux-omap@vger.kernel.org

On Mon, 2011-02-28 at 00:11 -0600, K, Mythri P wrote:
> Hi Tomi,
> 
> On Sun, Feb 27, 2011 at 3:47 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:

> >> + * 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
> >
> > Who is Yong Zhi and where's his signed-off-by?
> Yong zhi had written some of the functions in this file , which was in
> a library.He no longer works on the driver though .

Ok. Generally there should be a signed-off-by from everybody who has
written the code. It's like "I have written this code and I have
permission to send it upstream" etc.

His signed-off would be good for this too, but if the code is just based
on his work, and doesn't really resemble it anymore, perhaps you could
then say "Based on code by Yong Zhi", or similar.

> >> +
> >> +static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx,
> >> +                               int b2, int b1, u32 val)
> >> +{
> >> +       u32 t = 0;
> >> +       while (val != FLD_GET(hdmi_read_reg(idx), b2, b1)) {
> >
> > There's REG_GET macro used in other DSS files to read bits from the
> > registers.
> Hmm i see that in dsi.c REG_GET is defined to do the same,
> #define REG_GET(idx, start, end) \
>         FLD_GET(dsi_read_reg(idx), start, end)
> So should this be fine of should i define a new REG_GET ?

REG_GET() uses the private dsi_read_reg() function, so it has to be
defined again in each interface file. So for HDMI, define REG_REG
similarly with hdmi_read_reg().

> >> +       /* HACK : DDC needs time to stablize */
> >> +       mdelay(10);
> >
> > So what is the reason for this? It's a sleep that for unknown reason
> > make the code work? Or is there an idea why this is needed?
> This is the time it needs to stabilize DDC, else most of the time it
> reads a 0 or
> wrong shifted values , so i have prefixed with a HACK.

Ok. I'm fine with the hack for now, but I'm just interested: Is the 10ms
just something that happens to work? This sleep is not discussed in any
documentation? Has this been discussed with HW people?

> >> +static inline void print_omap_video_timings(struct omap_video_timings *timings)
> >
> > Why is this inline?
> Its only a print function , called many times by the driver. Do you
> see any reason not to make it inline?

Well, generally you shouldn't use inline. I think that's the basic rule.
Compiler usually makes better choices than humans. I have used them for
xxx_read_reg() and xxx_write_reg(), although I'm not quite sure if even
that is needed.

And in this case the function is quite long. I'm guessing here, but most
likely the code runs faster if it's _not_ inlined, because not inlining
reduces the size of the code. Also, print functions are on the slower
side anyway, so the overhead of calling this function is probably
negligible compared to the contents of the function. 

 Tomi



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 5/8] OMAP4 : DSS2 : HDMI: HDMI driver addition in the DSS drivers interface
  2011-02-28  6:27       ` Tomi Valkeinen
@ 2011-02-28  6:30         ` K, Mythri P
  2011-02-28  6:51           ` Tomi Valkeinen
  0 siblings, 1 reply; 23+ messages in thread
From: K, Mythri P @ 2011-02-28  6:30 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap@vger.kernel.org

Hi Tomi,

On Mon, Feb 28, 2011 at 11:57 AM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> On Mon, 2011-02-28 at 00:11 -0600, K, Mythri P wrote:
>> Hi Tomi,
>>
>> On Sun, Feb 27, 2011 at 3:47 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
>
>> >> + * 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
>> >
>> > Who is Yong Zhi and where's his signed-off-by?
>> Yong zhi had written some of the functions in this file , which was in
>> a library.He no longer works on the driver though .
>
> Ok. Generally there should be a signed-off-by from everybody who has
> written the code. It's like "I have written this code and I have
> permission to send it upstream" etc.
>
> His signed-off would be good for this too, but if the code is just based
> on his work, and doesn't really resemble it anymore, perhaps you could
> then say "Based on code by Yong Zhi", or similar.
>
sure i shall check with him to add his sign-off.
>> >> +
>> >> +static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx,
>> >> +                               int b2, int b1, u32 val)
>> >> +{
>> >> +       u32 t = 0;
>> >> +       while (val != FLD_GET(hdmi_read_reg(idx), b2, b1)) {
>> >
>> > There's REG_GET macro used in other DSS files to read bits from the
>> > registers.
>> Hmm i see that in dsi.c REG_GET is defined to do the same,
>> #define REG_GET(idx, start, end) \
>>         FLD_GET(dsi_read_reg(idx), start, end)
>> So should this be fine of should i define a new REG_GET ?
>
> REG_GET() uses the private dsi_read_reg() function, so it has to be
> defined again in each interface file. So for HDMI, define REG_REG
> similarly with hdmi_read_reg().
>
But it is used in only one function here , so is it really needed :) ?

>> >> +       /* HACK : DDC needs time to stablize */
>> >> +       mdelay(10);
>> >
>> > So what is the reason for this? It's a sleep that for unknown reason
>> > make the code work? Or is there an idea why this is needed?
>> This is the time it needs to stabilize DDC, else most of the time it
>> reads a 0 or
>> wrong shifted values , so i have prefixed with a HACK.
>
> Ok. I'm fine with the hack for now, but I'm just interested: Is the 10ms
> just something that happens to work? This sleep is not discussed in any
> documentation? Has this been discussed with HW people?

yes i have checked with the silicon validation.
>
>> >> +static inline void print_omap_video_timings(struct omap_video_timings *timings)
>> >
>> > Why is this inline?
>> Its only a print function , called many times by the driver. Do you
>> see any reason not to make it inline?
>
> Well, generally you shouldn't use inline. I think that's the basic rule.
> Compiler usually makes better choices than humans. I have used them for
> xxx_read_reg() and xxx_write_reg(), although I'm not quite sure if even
> that is needed.
>
> And in this case the function is quite long. I'm guessing here, but most
> likely the code runs faster if it's _not_ inlined, because not inlining
> reduces the size of the code. Also, print functions are on the slower
> side anyway, so the overhead of calling this function is probably
> negligible compared to the contents of the function.
>
ok i shall change.

>  Tomi
>
>
>

Thanks and regards,
Mythri.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 3/8] OMAP4 : DSS : HDMI: HDMI specific display controller and dss change.
  2011-02-28  6:21     ` K, Mythri P
@ 2011-02-28  6:42       ` Tomi Valkeinen
  0 siblings, 0 replies; 23+ messages in thread
From: Tomi Valkeinen @ 2011-02-28  6:42 UTC (permalink / raw)
  To: K, Mythri P; +Cc: linux-omap@vger.kernel.org

On Mon, 2011-02-28 at 00:21 -0600, K, Mythri P wrote:
> Hi Tomi,
> 
> On Sun, Feb 27, 2011 at 2:53 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> > On Fri, 2011-02-25 at 08:21 -0600, K, Mythri P wrote:
> >> Adding changes to set gamma table bit for TV interface and function to select
> >> between VENC and HDMI.
> >>
> >> Signed-off-by: Mythri P K <mythripk@ti.com>
> >> ---
> >>  drivers/video/omap2/dss/dispc.c |    5 +++++
> >>  drivers/video/omap2/dss/dss.c   |    7 +++++++
> >>  drivers/video/omap2/dss/dss.h   |    2 ++
> >>  3 files changed, 14 insertions(+), 0 deletions(-)
> >>
> >> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
> >> index 6d9bb17..16f1106 100644
> >> --- a/drivers/video/omap2/dss/dispc.c
> >> +++ b/drivers/video/omap2/dss/dispc.c
> >> @@ -1213,6 +1213,11 @@ void dispc_enable_zorder(enum omap_plane plane, bool enable)
> >>       dispc_write_reg(dispc_reg_att[plane], val);
> >>  }
> >>
> >> +void dispc_enable_gamma_table(bool enable)
> >> +{
> >> +     REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
> >> +}
> >> +
> >>  static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
> >>  {
> >>       u32 val;
> >> diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
> >> index 99de4e1..127d42e 100644
> >> --- a/drivers/video/omap2/dss/dss.c
> >> +++ b/drivers/video/omap2/dss/dss.c
> >> @@ -559,6 +559,13 @@ void dss_set_dac_pwrdn_bgz(bool enable)
> >>       REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
> >>  }
> >>
> >> +void dss_select_hdmi_venc(bool hdmi)
> >> +{
> >> +     REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* 0x1 for HDMI, 0x0 VENC */
> >> +     if (hdmi)
> >> +             REG_FLD_MOD(DSS_CONTROL, 0, 9, 8);
> >> +}
> >
> > bool argument for this function is very confusing. Which one is true?
> > Perhaps this could use an enum.
> I have added a comment , 1 is for HDMI and 0 for VENC.

Yes, but I meant the code which calls this function =). Usually boolean
argument is not good if you have to select between x and y. It's
impossible for the reader to know which is which. 

> >
> > I've tried to keep the habit of having the name of the register field in
> > comments to make the code easier to read. For example, /*
> > VENC_HDMI_SWITCH */ for the bit 15.
> I can add this.
> >
> > The bits 8 and 9 are FCK_CLK_SWITCH. Why do you set it here? Looks
> > rather dangerous to change the clock source like that.
> >
> This is to select what would be the clock source to DISPC, HDMI would
> need the DISPC
> to run at the rate of pixel clock (TMDS if deep color is set ) required by HDMI.
> Where as DSI does not have any such constraint( correct me if i am wrong).

Hmm, I don't understand. This selects the DISPC to receive the fck from
PRCM. Why does it matter for HDMI where DISPC gets its clock? Is this
described in the TRM?

> I suppose we can have a patch to select the correct clock source to
> DISPC dynamically
> based on what panels are connected later on ?

Well, something more generic is required, because other parts of the
code could make changes to the fclk source. Here you just set the source
clock register directly and invisibly. You don't even use the function
dss_select_dispc_clk_source(), and so this would mess up the
dss.dispc_clk_source variable.

 Tomi



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 5/8] OMAP4 : DSS2 : HDMI: HDMI driver addition in the DSS drivers interface
  2011-02-28  6:30         ` K, Mythri P
@ 2011-02-28  6:51           ` Tomi Valkeinen
  0 siblings, 0 replies; 23+ messages in thread
From: Tomi Valkeinen @ 2011-02-28  6:51 UTC (permalink / raw)
  To: K, Mythri P; +Cc: linux-omap@vger.kernel.org

On Mon, 2011-02-28 at 00:30 -0600, K, Mythri P wrote:
> Hi Tomi,
> 
> On Mon, Feb 28, 2011 at 11:57 AM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> > On Mon, 2011-02-28 at 00:11 -0600, K, Mythri P wrote:
> >> Hi Tomi,
> >>
> >> On Sun, Feb 27, 2011 at 3:47 PM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> >
> >> >> + * 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
> >> >
> >> > Who is Yong Zhi and where's his signed-off-by?
> >> Yong zhi had written some of the functions in this file , which was in
> >> a library.He no longer works on the driver though .
> >
> > Ok. Generally there should be a signed-off-by from everybody who has
> > written the code. It's like "I have written this code and I have
> > permission to send it upstream" etc.
> >
> > His signed-off would be good for this too, but if the code is just based
> > on his work, and doesn't really resemble it anymore, perhaps you could
> > then say "Based on code by Yong Zhi", or similar.
> >
> sure i shall check with him to add his sign-off.
> >> >> +
> >> >> +static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx,
> >> >> +                               int b2, int b1, u32 val)
> >> >> +{
> >> >> +       u32 t = 0;
> >> >> +       while (val != FLD_GET(hdmi_read_reg(idx), b2, b1)) {
> >> >
> >> > There's REG_GET macro used in other DSS files to read bits from the
> >> > registers.
> >> Hmm i see that in dsi.c REG_GET is defined to do the same,
> >> #define REG_GET(idx, start, end) \
> >>         FLD_GET(dsi_read_reg(idx), start, end)
> >> So should this be fine of should i define a new REG_GET ?
> >
> > REG_GET() uses the private dsi_read_reg() function, so it has to be
> > defined again in each interface file. So for HDMI, define REG_REG
> > similarly with hdmi_read_reg().
> >
> But it is used in only one function here , so is it really needed :) ?

There are more than one FLD_GET(hdmi_read_reg()) patterns in hdmi.c,
which could be replaced with REG_FLD_GET(). But granted, there are still
not many of them now that I checked. Well, up to you if you want to add
that or not.

> >> >> +       /* HACK : DDC needs time to stablize */
> >> >> +       mdelay(10);
> >> >
> >> > So what is the reason for this? It's a sleep that for unknown reason
> >> > make the code work? Or is there an idea why this is needed?
> >> This is the time it needs to stabilize DDC, else most of the time it
> >> reads a 0 or
> >> wrong shifted values , so i have prefixed with a HACK.
> >
> > Ok. I'm fine with the hack for now, but I'm just interested: Is the 10ms
> > just something that happens to work? This sleep is not discussed in any
> > documentation? Has this been discussed with HW people?
> 
> yes i have checked with the silicon validation.

Hmm. So, it's a HW feature or a HW bug? In either case, it's not a hack
then. If it's a normal HW feature, you just need to sleep there, simple
as that. If it's a HW bug, then this is a work-around, and it should be
mentioned.

Generally code like this should have a bit more explanation whether it's
a HW bug, HW feature, SW hack that magically makes it work, SW hack made
to get difficult thing done quickly and to be replaced later, etc. The
reader should understand what's going on here, and what can be done for
the code.

Also, I only now noticed that it's a mdelay, not msleep. 10ms mdelay
sounds very bad, don't do that. Use msleep. mdelay is basically a 10ms
busy loop.

 Tomi



^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2011-02-28  6:51 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-25 14:21 [PATCH 0/8] OMAP4 : DSS2 : HDMI support Mythri P K
2011-02-25 14:21 ` [PATCH 1/8] OMAP4 : DSS2 : Add display type HDMI to DSS2 Mythri P K
2011-02-25 14:21 ` [PATCH 2/8] OMAP4 : DSS2 : Add display structure in the board file for OMAP4 sdp Mythri P K
2011-02-27  9:13   ` Tomi Valkeinen
2011-02-28  5:32     ` K, Mythri P
2011-02-25 14:21 ` [PATCH 3/8] OMAP4 : DSS : HDMI: HDMI specific display controller and dss change Mythri P K
2011-02-27  9:23   ` Tomi Valkeinen
2011-02-28  6:21     ` K, Mythri P
2011-02-28  6:42       ` Tomi Valkeinen
2011-02-25 14:21 ` [PATCH 4/8] OMAP4 : DSS : HDMI: HDMI driver header file addition Mythri P K
2011-02-27  9:28   ` Tomi Valkeinen
2011-02-28  5:40     ` K, Mythri P
2011-02-25 14:21 ` [PATCH 5/8] OMAP4 : DSS2 : HDMI: HDMI driver addition in the DSS drivers interface Mythri P K
2011-02-27 10:17   ` Tomi Valkeinen
2011-02-28  6:11     ` K, Mythri P
2011-02-28  6:27       ` Tomi Valkeinen
2011-02-28  6:30         ` K, Mythri P
2011-02-28  6:51           ` Tomi Valkeinen
2011-02-25 14:21 ` [PATCH 6/8] OMAP4 : DSS2 : HDMI: HDMI panel driver addition in the DSS Mythri P K
2011-02-27  9:43   ` Tomi Valkeinen
2011-02-28  6:14     ` K, Mythri P
2011-02-25 14:21 ` [PATCH 7/8] OMAP4 : DSS : HDMI: Call to HDMI module init to register driver Mythri P K
2011-02-25 14:21 ` [PATCH 8/8] OMAP4 : DSS2 : Add display structure in the board file for OMAP4 pandaboard Mythri P K

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox