All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] OMAP: DSS2: DSI: Initial DSI video mode support
@ 2011-08-30 10:51 Archit Taneja
  2011-08-30 10:51 ` [PATCH 01/10] OMAP: DSS2: Use MIPI DSI transacition types and commands from include/video/mipi_display.h Archit Taneja
                   ` (9 more replies)
  0 siblings, 10 replies; 19+ messages in thread
From: Archit Taneja @ 2011-08-30 10:51 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

This provided initial support for DSI Video Mode. The first 6 patches are
not directly related to video mode, but they add required features and cleanup
for supporting video mode cleanly.

Support for a panel driver supporting video mode is not added yet since no
OMAP platfrom support in mainline has a video mode panel.

The Blaze tablet with the toshiba bridge chip "TC358765" is used as an example
to validate video mode support. The patches to enable blaze tablet and the
bridge chip are provided in the following tree along with the DSI video mode
patches:

https://gitorious.org/~boddob/linux-omap-dss2/archit-dss2-clone/commits/video-mode-4

Archit Taneja (10):
  OMAP: DSS2: Use MIPI DSI transacition types and commands from
    include/video/mipi_display.h
  OMAP: DSS2: DSI: Represent L4 and VP as sources of VC instead of
    modes
  OMAP: DSS2: Create enum for DSI operation modes
  OMAP: DSS2: DSI: Introduce generic write functions
  OMAP: DSS2: DSI: Remove functions dsi_vc_dcs_read_1() and
    dsi_vc_dcs_read_2()
  OMAP: DSS2: DSI: Split dsi_vc_dcs_read() into 2 functions
  OMAP: DSS2: DSI: Introduce generic read functions
  OMAP: DSS2: Clean up stallmode and io pad mode selection
  OMAP: DSS2: Create an enum for DSI pixel formats
  OMAP: DSS2: DSI Video mode support

 drivers/video/omap2/displays/panel-taal.c |   47 +--
 drivers/video/omap2/dss/dispc.c           |   47 +--
 drivers/video/omap2/dss/dpi.c             |    5 +-
 drivers/video/omap2/dss/dsi.c             |  675 ++++++++++++++++++++++-------
 drivers/video/omap2/dss/dss.h             |   17 +-
 drivers/video/omap2/dss/rfbi.c            |    4 +-
 drivers/video/omap2/dss/sdi.c             |    4 +-
 include/video/omapdss.h                   |   69 +++-
 8 files changed, 636 insertions(+), 232 deletions(-)


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

* [PATCH 01/10] OMAP: DSS2: Use MIPI DSI transacition types and commands from include/video/mipi_display.h
  2011-08-30 10:51 [PATCH 00/10] OMAP: DSS2: DSI: Initial DSI video mode support Archit Taneja
@ 2011-08-30 10:51 ` Archit Taneja
  2011-08-30 10:51 ` [PATCH 02/10] OMAP: DSS2: DSI: Represent L4 and VP as sources of VC instead of modes Archit Taneja
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Archit Taneja @ 2011-08-30 10:51 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

MIPI DSI Transaction types and DCS commands are currently defined as macros in
dsi.c and panel-taal.c, remove these and replace them with enum members defined
in include/video/mipi_display.h.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-taal.c |   45 +++++++++-----------------
 drivers/video/omap2/dss/dsi.c             |   48 +++++++++++-----------------
 2 files changed, 35 insertions(+), 58 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 4e888ac..7675687 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -35,26 +35,12 @@
 
 #include <video/omapdss.h>
 #include <video/omap-panel-nokia-dsi.h>
+#include <video/mipi_display.h>
 
 /* DSI Virtual channel. Hardcoded for now. */
 #define TCH 0
 
 #define DCS_READ_NUM_ERRORS	0x05
-#define DCS_READ_POWER_MODE	0x0a
-#define DCS_READ_MADCTL		0x0b
-#define DCS_READ_PIXEL_FORMAT	0x0c
-#define DCS_RDDSDR		0x0f
-#define DCS_SLEEP_IN		0x10
-#define DCS_SLEEP_OUT		0x11
-#define DCS_DISPLAY_OFF		0x28
-#define DCS_DISPLAY_ON		0x29
-#define DCS_COLUMN_ADDR		0x2a
-#define DCS_PAGE_ADDR		0x2b
-#define DCS_MEMORY_WRITE	0x2c
-#define DCS_TEAR_OFF		0x34
-#define DCS_TEAR_ON		0x35
-#define DCS_MEM_ACC_CTRL	0x36
-#define DCS_PIXEL_FORMAT	0x3a
 #define DCS_BRIGHTNESS		0x51
 #define DCS_CTRL_DISPLAY	0x53
 #define DCS_WRITE_CABC		0x55
@@ -302,7 +288,7 @@ static int taal_sleep_in(struct taal_data *td)
 
 	hw_guard_wait(td);
 
-	cmd = DCS_SLEEP_IN;
+	cmd = MIPI_DCS_ENTER_SLEEP_MODE;
 	r = dsi_vc_dcs_write_nosync(td->dssdev, td->channel, &cmd, 1);
 	if (r)
 		return r;
@@ -321,7 +307,7 @@ static int taal_sleep_out(struct taal_data *td)
 
 	hw_guard_wait(td);
 
-	r = taal_dcs_write_0(td, DCS_SLEEP_OUT);
+	r = taal_dcs_write_0(td, MIPI_DCS_EXIT_SLEEP_MODE);
 	if (r)
 		return r;
 
@@ -356,7 +342,7 @@ static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
 	u8 mode;
 	int b5, b6, b7;
 
-	r = taal_dcs_read_1(td, DCS_READ_MADCTL, &mode);
+	r = taal_dcs_read_1(td, MIPI_DCS_GET_ADDRESS_MODE, &mode);
 	if (r)
 		return r;
 
@@ -390,7 +376,7 @@ static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
 	mode &= ~((1<<7) | (1<<6) | (1<<5));
 	mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
 
-	return taal_dcs_write_1(td, DCS_MEM_ACC_CTRL, mode);
+	return taal_dcs_write_1(td, MIPI_DCS_SET_ADDRESS_MODE, mode);
 }
 
 static int taal_set_update_window(struct taal_data *td,
@@ -403,7 +389,7 @@ static int taal_set_update_window(struct taal_data *td,
 	u16 y2 = y + h - 1;
 
 	u8 buf[5];
-	buf[0] = DCS_COLUMN_ADDR;
+	buf[0] = MIPI_DCS_SET_COLUMN_ADDRESS;
 	buf[1] = (x1 >> 8) & 0xff;
 	buf[2] = (x1 >> 0) & 0xff;
 	buf[3] = (x2 >> 8) & 0xff;
@@ -413,7 +399,7 @@ static int taal_set_update_window(struct taal_data *td,
 	if (r)
 		return r;
 
-	buf[0] = DCS_PAGE_ADDR;
+	buf[0] = MIPI_DCS_SET_PAGE_ADDRESS;
 	buf[1] = (y1 >> 8) & 0xff;
 	buf[2] = (y1 >> 0) & 0xff;
 	buf[3] = (y2 >> 8) & 0xff;
@@ -1195,7 +1181,8 @@ static int taal_power_on(struct omap_dss_device *dssdev)
 	if (r)
 		goto err;
 
-	r = taal_dcs_write_1(td, DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */
+	r = taal_dcs_write_1(td, MIPI_DCS_SET_PIXEL_FORMAT,
+		MIPI_DCS_PIXEL_FMT_24BIT);
 	if (r)
 		goto err;
 
@@ -1209,7 +1196,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
 			goto err;
 	}
 
-	r = taal_dcs_write_0(td, DCS_DISPLAY_ON);
+	r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_ON);
 	if (r)
 		goto err;
 
@@ -1246,7 +1233,7 @@ static void taal_power_off(struct omap_dss_device *dssdev)
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
 	int r;
 
-	r = taal_dcs_write_0(td, DCS_DISPLAY_OFF);
+	r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF);
 	if (!r)
 		r = taal_sleep_in(td);
 
@@ -1529,9 +1516,9 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
 	int r;
 
 	if (enable)
-		r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
+		r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
 	else
-		r = taal_dcs_write_0(td, DCS_TEAR_OFF);
+		r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF);
 
 	if (!panel_data->use_ext_te)
 		omapdss_dsi_enable_te(dssdev, enable);
@@ -1851,7 +1838,7 @@ static void taal_esd_work(struct work_struct *work)
 		goto err;
 	}
 
-	r = taal_dcs_read_1(td, DCS_RDDSDR, &state1);
+	r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state1);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to read Taal status\n");
 		goto err;
@@ -1864,7 +1851,7 @@ static void taal_esd_work(struct work_struct *work)
 		goto err;
 	}
 
-	r = taal_dcs_read_1(td, DCS_RDDSDR, &state2);
+	r = taal_dcs_read_1(td, MIPI_DCS_GET_DIAGNOSTIC_RESULT, &state2);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to read Taal status\n");
 		goto err;
@@ -1880,7 +1867,7 @@ static void taal_esd_work(struct work_struct *work)
 	/* Self-diagnostics result is also shown on TE GPIO line. We need
 	 * to re-enable TE after self diagnostics */
 	if (td->te_enabled && panel_data->use_ext_te) {
-		r = taal_dcs_write_1(td, DCS_TEAR_ON, 0);
+		r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
 		if (r)
 			goto err;
 	}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 52a4a02..6735e0c 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -39,6 +39,7 @@
 #include <linux/pm_runtime.h>
 
 #include <video/omapdss.h>
+#include <video/mipi_display.h>
 #include <plat/clock.h>
 
 #include "dss.h"
@@ -198,18 +199,6 @@ struct dsi_reg { u16 idx; };
 	 DSI_CIO_IRQ_ERRCONTENTIONLP0_4 | DSI_CIO_IRQ_ERRCONTENTIONLP1_4 | \
 	 DSI_CIO_IRQ_ERRCONTENTIONLP0_5 | DSI_CIO_IRQ_ERRCONTENTIONLP1_5)
 
-#define DSI_DT_DCS_SHORT_WRITE_0	0x05
-#define DSI_DT_DCS_SHORT_WRITE_1	0x15
-#define DSI_DT_DCS_READ			0x06
-#define DSI_DT_SET_MAX_RET_PKG_SIZE	0x37
-#define DSI_DT_NULL_PACKET		0x09
-#define DSI_DT_DCS_LONG_WRITE		0x39
-
-#define DSI_DT_RX_ACK_WITH_ERR		0x02
-#define DSI_DT_RX_DCS_LONG_READ		0x1c
-#define DSI_DT_RX_SHORT_READ_1		0x21
-#define DSI_DT_RX_SHORT_READ_2		0x22
-
 typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
 
 #define DSI_MAX_NR_ISRS                2
@@ -2887,16 +2876,16 @@ static u16 dsi_vc_flush_receive_data(struct platform_device *dsidev,
 		val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel));
 		DSSERR("\trawval %#08x\n", val);
 		dt = FLD_GET(val, 5, 0);
-		if (dt == DSI_DT_RX_ACK_WITH_ERR) {
+		if (dt == MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT) {
 			u16 err = FLD_GET(val, 23, 8);
 			dsi_show_rx_ack_with_err(err);
-		} else if (dt == DSI_DT_RX_SHORT_READ_1) {
+		} else if (dt == MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE) {
 			DSSERR("\tDCS short response, 1 byte: %#x\n",
 					FLD_GET(val, 23, 8));
-		} else if (dt == DSI_DT_RX_SHORT_READ_2) {
+		} else if (dt == MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE) {
 			DSSERR("\tDCS short response, 2 byte: %#x\n",
 					FLD_GET(val, 23, 8));
-		} else if (dt == DSI_DT_RX_DCS_LONG_READ) {
+		} else if (dt == MIPI_DSI_RX_DCS_LONG_READ_RESPONSE) {
 			DSSERR("\tDCS long response, len %d\n",
 					FLD_GET(val, 23, 8));
 			dsi_vc_flush_long_data(dsidev, channel);
@@ -3101,7 +3090,7 @@ int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel)
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	u8 nullpkg[] = {0, 0, 0, 0};
 
-	return dsi_vc_send_long(dsidev, channel, DSI_DT_NULL_PACKET, nullpkg,
+	return dsi_vc_send_long(dsidev, channel, MIPI_DSI_NULL_PACKET, nullpkg,
 		4, 0);
 }
 EXPORT_SYMBOL(dsi_vc_send_null);
@@ -3115,14 +3104,15 @@ int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
 	BUG_ON(len == 0);
 
 	if (len == 1) {
-		r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_SHORT_WRITE_0,
-				data[0], 0);
+		r = dsi_vc_send_short(dsidev, channel,
+				MIPI_DSI_DCS_SHORT_WRITE, data[0], 0);
 	} else if (len == 2) {
-		r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_SHORT_WRITE_1,
+		r = dsi_vc_send_short(dsidev, channel,
+				MIPI_DSI_DCS_SHORT_WRITE_PARAM,
 				data[0] | (data[1] << 8), 0);
 	} else {
 		/* 0x39 = DCS Long Write */
-		r = dsi_vc_send_long(dsidev, channel, DSI_DT_DCS_LONG_WRITE,
+		r = dsi_vc_send_long(dsidev, channel, MIPI_DSI_DCS_LONG_WRITE,
 				data, len, 0);
 	}
 
@@ -3188,7 +3178,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 	if (dsi->debug_read)
 		DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, dcs_cmd);
 
-	r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_READ, dcs_cmd, 0);
+	r = dsi_vc_send_short(dsidev, channel, MIPI_DSI_DCS_READ, dcs_cmd, 0);
 	if (r)
 		goto err;
 
@@ -3207,13 +3197,13 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 	if (dsi->debug_read)
 		DSSDBG("\theader: %08x\n", val);
 	dt = FLD_GET(val, 5, 0);
-	if (dt == DSI_DT_RX_ACK_WITH_ERR) {
+	if (dt == MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT) {
 		u16 err = FLD_GET(val, 23, 8);
 		dsi_show_rx_ack_with_err(err);
 		r = -EIO;
 		goto err;
 
-	} else if (dt == DSI_DT_RX_SHORT_READ_1) {
+	} else if (dt == MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE) {
 		u8 data = FLD_GET(val, 15, 8);
 		if (dsi->debug_read)
 			DSSDBG("\tDCS short response, 1 byte: %02x\n", data);
@@ -3226,7 +3216,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 		buf[0] = data;
 
 		return 1;
-	} else if (dt == DSI_DT_RX_SHORT_READ_2) {
+	} else if (dt == MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE) {
 		u16 data = FLD_GET(val, 23, 8);
 		if (dsi->debug_read)
 			DSSDBG("\tDCS short response, 2 byte: %04x\n", data);
@@ -3240,7 +3230,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 		buf[1] = (data >> 8) & 0xff;
 
 		return 2;
-	} else if (dt == DSI_DT_RX_DCS_LONG_READ) {
+	} else if (dt == MIPI_DSI_RX_DCS_LONG_READ_RESPONSE) {
 		int w;
 		int len = FLD_GET(val, 23, 8);
 		if (dsi->debug_read)
@@ -3330,8 +3320,8 @@ int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 
-	return dsi_vc_send_short(dsidev, channel, DSI_DT_SET_MAX_RET_PKG_SIZE,
-			len, 0);
+	return dsi_vc_send_short(dsidev, channel,
+			MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, len, 0);
 }
 EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size);
 
@@ -3690,7 +3680,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
 	l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
 	dsi_write_reg(dsidev, DSI_VC_TE(channel), l);
 
-	dsi_vc_write_long_header(dsidev, channel, DSI_DT_DCS_LONG_WRITE,
+	dsi_vc_write_long_header(dsidev, channel, MIPI_DSI_DCS_LONG_WRITE,
 		packet_len, 0);
 
 	if (dsi->te_enabled)
-- 
1.7.1


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

* [PATCH 02/10] OMAP: DSS2: DSI: Represent L4 and VP as sources of VC instead of modes
  2011-08-30 10:51 [PATCH 00/10] OMAP: DSS2: DSI: Initial DSI video mode support Archit Taneja
  2011-08-30 10:51 ` [PATCH 01/10] OMAP: DSS2: Use MIPI DSI transacition types and commands from include/video/mipi_display.h Archit Taneja
@ 2011-08-30 10:51 ` Archit Taneja
  2011-08-30 10:51 ` [PATCH 03/10] OMAP: DSS2: Create enum for DSI operation modes Archit Taneja
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Archit Taneja @ 2011-08-30 10:51 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

The enum type dsi_vc_mode is a bit misleading as L4 slave port and video port
are sources to VC rather than the mode of operation. Rename then enum type and
its members. Merge dsi_vc_config_vp() and dsi_vc_config_l4() into a single
function called dsi_vc_config_source() which takes dsi_vc_source enum as an
extra argument.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dsi.c |   72 ++++++++++++-----------------------------
 1 files changed, 21 insertions(+), 51 deletions(-)

diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 6735e0c..bdc2c9d 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -217,9 +217,9 @@ enum fifo_size {
 	DSI_FIFO_SIZE_128	= 4,
 };
 
-enum dsi_vc_mode {
-	DSI_VC_MODE_L4 = 0,
-	DSI_VC_MODE_VP,
+enum dsi_vc_source {
+	DSI_VC_SOURCE_L4 = 0,
+	DSI_VC_SOURCE_VP,
 };
 
 enum dsi_lane {
@@ -272,7 +272,7 @@ struct dsi_data {
 	struct regulator *vdds_dsi_reg;
 
 	struct {
-		enum dsi_vc_mode mode;
+		enum dsi_vc_source source;
 		struct omap_dss_device *dssdev;
 		enum fifo_size fifo_size;
 		int vc_id;
@@ -2672,10 +2672,10 @@ static int dsi_sync_vc(struct platform_device *dsidev, int channel)
 	if (!dsi_vc_is_enabled(dsidev, channel))
 		return 0;
 
-	switch (dsi->vc[channel].mode) {
-	case DSI_VC_MODE_VP:
+	switch (dsi->vc[channel].source) {
+	case DSI_VC_SOURCE_VP:
 		return dsi_sync_vc_vp(dsidev, channel);
-	case DSI_VC_MODE_L4:
+	case DSI_VC_SOURCE_L4:
 		return dsi_sync_vc_l4(dsidev, channel);
 	default:
 		BUG();
@@ -2729,43 +2729,12 @@ static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
 	dsi_write_reg(dsidev, DSI_VC_CTRL(channel), r);
 }
 
-static int dsi_vc_config_l4(struct platform_device *dsidev, int channel)
+static int dsi_vc_config_source(struct platform_device *dsidev, int channel,
+		enum dsi_vc_source source)
 {
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
-	if (dsi->vc[channel].mode == DSI_VC_MODE_L4)
-		return 0;
-
-	DSSDBGF("%d", channel);
-
-	dsi_sync_vc(dsidev, channel);
-
-	dsi_vc_enable(dsidev, channel, 0);
-
-	/* VC_BUSY */
-	if (wait_for_bit_change(dsidev, DSI_VC_CTRL(channel), 15, 0) != 0) {
-		DSSERR("vc(%d) busy when trying to config for L4\n", channel);
-		return -EIO;
-	}
-
-	REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */
-
-	/* DCS_CMD_ENABLE */
-	if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC))
-		REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 30, 30);
-
-	dsi_vc_enable(dsidev, channel, 1);
-
-	dsi->vc[channel].mode = DSI_VC_MODE_L4;
-
-	return 0;
-}
-
-static int dsi_vc_config_vp(struct platform_device *dsidev, int channel)
-{
-	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
-
-	if (dsi->vc[channel].mode == DSI_VC_MODE_VP)
+	if (dsi->vc[channel].source == source)
 		return 0;
 
 	DSSDBGF("%d", channel);
@@ -2780,21 +2749,22 @@ static int dsi_vc_config_vp(struct platform_device *dsidev, int channel)
 		return -EIO;
 	}
 
-	/* SOURCE, 1 = video port */
-	REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 1, 1);
+	/* SOURCE, 0 = L4, 1 = video port */
+	REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), source, 1, 1);
 
 	/* DCS_CMD_ENABLE */
-	if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC))
-		REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 30, 30);
+	if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) {
+		bool enable = source == DSI_VC_SOURCE_VP;
+		REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), enable, 30, 30);
+	}
 
 	dsi_vc_enable(dsidev, channel, 1);
 
-	dsi->vc[channel].mode = DSI_VC_MODE_VP;
+	dsi->vc[channel].source = source;
 
 	return 0;
 }
 
-
 void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
 		bool enable)
 {
@@ -3010,7 +2980,7 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel,
 		return -EINVAL;
 	}
 
-	dsi_vc_config_l4(dsidev, channel);
+	dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_L4);
 
 	dsi_vc_write_long_header(dsidev, channel, data_type, len, ecc);
 
@@ -3069,7 +3039,7 @@ static int dsi_vc_send_short(struct platform_device *dsidev, int channel,
 				channel,
 				data_type, data & 0xff, (data >> 8) & 0xff);
 
-	dsi_vc_config_l4(dsidev, channel);
+	dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_L4);
 
 	if (FLD_GET(dsi_read_reg(dsidev, DSI_VC_CTRL(channel)), 16, 16)) {
 		DSSERR("ERROR FIFO FULL, aborting transfer\n");
@@ -3657,7 +3627,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
 	DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
 			x, y, w, h);
 
-	dsi_vc_config_vp(dsidev, channel);
+	dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_VP);
 
 	bytespp	= dssdev->ctrl.pixel_size / 8;
 	bytespl = w * bytespp;
@@ -4383,7 +4353,7 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
 
 	/* DSI VCs initialization */
 	for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {
-		dsi->vc[i].mode = DSI_VC_MODE_L4;
+		dsi->vc[i].source = DSI_VC_SOURCE_L4;
 		dsi->vc[i].dssdev = NULL;
 		dsi->vc[i].vc_id = 0;
 	}
-- 
1.7.1


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

* [PATCH 03/10] OMAP: DSS2: Create enum for DSI operation modes
  2011-08-30 10:51 [PATCH 00/10] OMAP: DSS2: DSI: Initial DSI video mode support Archit Taneja
  2011-08-30 10:51 ` [PATCH 01/10] OMAP: DSS2: Use MIPI DSI transacition types and commands from include/video/mipi_display.h Archit Taneja
  2011-08-30 10:51 ` [PATCH 02/10] OMAP: DSS2: DSI: Represent L4 and VP as sources of VC instead of modes Archit Taneja
@ 2011-08-30 10:51 ` Archit Taneja
  2011-08-30 10:51 ` [PATCH 04/10] OMAP: DSS2: DSI: Introduce generic write functions Archit Taneja
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Archit Taneja @ 2011-08-30 10:51 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

Create an enum for DSI operation modes, use this to set the capabilities of the
device in dsi_init_display().

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dsi.c |    7 ++++---
 include/video/omapdss.h       |    7 +++++++
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index bdc2c9d..d3bffe8 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4123,9 +4123,10 @@ int dsi_init_display(struct omap_dss_device *dssdev)
 
 	DSSDBG("DSI init\n");
 
-	/* XXX these should be figured out dynamically */
-	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
-		OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
+	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
+		dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
+			OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
+	}
 
 	if (dsi->vdds_dsi_reg == NULL) {
 		struct regulator *vdds_dsi;
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 9398dd3..2babe7e 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -129,6 +129,11 @@ enum omap_dss_venc_type {
 	OMAP_DSS_VENC_TYPE_SVIDEO,
 };
 
+enum omap_dss_dsi_mode {
+	OMAP_DSS_DSI_CMD_MODE = 0,
+	OMAP_DSS_DSI_VIDEO_MODE,
+};
+
 enum omap_display_caps {
 	OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE	= 1 << 0,
 	OMAP_DSS_DISPLAY_CAP_TEAR_ELIM		= 1 << 1,
@@ -473,6 +478,8 @@ struct omap_dss_device {
 		int acb;	/* ac-bias pin frequency */
 
 		enum omap_panel_config config;
+
+		enum omap_dss_dsi_mode dsi_mode;
 	} panel;
 
 	struct {
-- 
1.7.1


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

* [PATCH 04/10] OMAP: DSS2: DSI: Introduce generic write functions
  2011-08-30 10:51 [PATCH 00/10] OMAP: DSS2: DSI: Initial DSI video mode support Archit Taneja
                   ` (2 preceding siblings ...)
  2011-08-30 10:51 ` [PATCH 03/10] OMAP: DSS2: Create enum for DSI operation modes Archit Taneja
@ 2011-08-30 10:51 ` Archit Taneja
  2011-08-30 10:51 ` [PATCH 05/10] OMAP: DSS2: DSI: Remove functions dsi_vc_dcs_read_1() and dsi_vc_dcs_read_2() Archit Taneja
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Archit Taneja @ 2011-08-30 10:51 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

Intoduce enum "dss_dsi_content_type" to differentiate between DCS and generic
content types.

Introduce short and long packet write functions which use generic
Processor-to-Peripheral transaction types. These are needed by some devices
which may not support corresponding DCS commands. Create common write functions
which allow code reuse between DCS and generic write functions.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dsi.c |   84 +++++++++++++++++++++++++++++++++++------
 drivers/video/omap2/dss/dss.h |    5 ++
 include/video/omapdss.h       |   12 +++++-
 3 files changed, 87 insertions(+), 14 deletions(-)

diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index d3bffe8..bb55889 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -3065,38 +3065,60 @@ int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel)
 }
 EXPORT_SYMBOL(dsi_vc_send_null);
 
-int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
-		u8 *data, int len)
+static int dsi_vc_write_nosync_common(struct omap_dss_device *dssdev,
+		int channel, u8 *data, int len, enum dss_dsi_content_type type)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	int r;
 
-	BUG_ON(len == 0);
-
-	if (len == 1) {
+	if (len == 0) {
+		BUG_ON(type == DSS_DSI_CONTENT_DCS);
 		r = dsi_vc_send_short(dsidev, channel,
+				MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM, 0, 0);
+	} else if (len == 1) {
+		r = dsi_vc_send_short(dsidev, channel,
+				type == DSS_DSI_CONTENT_GENERIC ?
+				MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM :
 				MIPI_DSI_DCS_SHORT_WRITE, data[0], 0);
 	} else if (len == 2) {
 		r = dsi_vc_send_short(dsidev, channel,
+				type == DSS_DSI_CONTENT_GENERIC ?
+				MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM :
 				MIPI_DSI_DCS_SHORT_WRITE_PARAM,
 				data[0] | (data[1] << 8), 0);
 	} else {
-		/* 0x39 = DCS Long Write */
-		r = dsi_vc_send_long(dsidev, channel, MIPI_DSI_DCS_LONG_WRITE,
-				data, len, 0);
+		r = dsi_vc_send_long(dsidev, channel,
+				type == DSS_DSI_CONTENT_GENERIC ?
+				MIPI_DSI_GENERIC_LONG_WRITE :
+				MIPI_DSI_DCS_LONG_WRITE, data, len, 0);
 	}
 
 	return r;
 }
+
+int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
+		u8 *data, int len)
+{
+	return dsi_vc_write_nosync_common(dssdev, channel, data, len,
+			DSS_DSI_CONTENT_DCS);
+}
 EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
 
-int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
-		int len)
+int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel,
+		u8 *data, int len)
+{
+	return dsi_vc_write_nosync_common(dssdev, channel, data, len,
+			DSS_DSI_CONTENT_GENERIC);
+}
+EXPORT_SYMBOL(dsi_vc_generic_write_nosync);
+
+static int dsi_vc_write_common(struct omap_dss_device *dssdev, int channel,
+		u8 *data, int len, enum dss_dsi_content_type type)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	int r;
 
-	r = dsi_vc_dcs_write_nosync(dssdev, channel, data, len);
+	r = dsi_vc_write_nosync_common(dssdev, channel, data, len, type);
 	if (r)
 		goto err;
 
@@ -3114,18 +3136,39 @@ int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
 
 	return 0;
 err:
-	DSSERR("dsi_vc_dcs_write(ch %d, cmd 0x%02x, len %d) failed\n",
+	DSSERR("dsi_vc_write_common(ch %d, cmd 0x%02x, len %d) failed\n",
 			channel, data[0], len);
 	return r;
 }
+
+int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
+		int len)
+{
+	return dsi_vc_write_common(dssdev, channel, data, len,
+			DSS_DSI_CONTENT_DCS);
+}
 EXPORT_SYMBOL(dsi_vc_dcs_write);
 
+int dsi_vc_generic_write(struct omap_dss_device *dssdev, int channel, u8 *data,
+		int len)
+{
+	return dsi_vc_write_common(dssdev, channel, data, len,
+			DSS_DSI_CONTENT_GENERIC);
+}
+EXPORT_SYMBOL(dsi_vc_generic_write);
+
 int dsi_vc_dcs_write_0(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd)
 {
 	return dsi_vc_dcs_write(dssdev, channel, &dcs_cmd, 1);
 }
 EXPORT_SYMBOL(dsi_vc_dcs_write_0);
 
+int dsi_vc_generic_write_0(struct omap_dss_device *dssdev, int channel)
+{
+	return dsi_vc_generic_write(dssdev, channel, NULL, 0);
+}
+EXPORT_SYMBOL(dsi_vc_generic_write_0);
+
 int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 		u8 param)
 {
@@ -3136,6 +3179,23 @@ int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 }
 EXPORT_SYMBOL(dsi_vc_dcs_write_1);
 
+int dsi_vc_generic_write_1(struct omap_dss_device *dssdev, int channel,
+		u8 param)
+{
+	return dsi_vc_generic_write(dssdev, channel, &param, 1);
+}
+EXPORT_SYMBOL(dsi_vc_generic_write_1);
+
+int dsi_vc_generic_write_2(struct omap_dss_device *dssdev, int channel,
+		u8 param1, u8 param2)
+{
+	u8 buf[2];
+	buf[0] = param1;
+	buf[1] = param2;
+	return dsi_vc_generic_write(dssdev, channel, buf, 2);
+}
+EXPORT_SYMBOL(dsi_vc_generic_write_2);
+
 int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 		u8 *buf, int buflen)
 {
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index a095a62..3ec8dd7 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -108,6 +108,11 @@ enum dss_hdmi_venc_clk_source_select {
 	DSS_HDMI_M_PCLK = 1,
 };
 
+enum dss_dsi_content_type {
+	DSS_DSI_CONTENT_DCS,
+	DSS_DSI_CONTENT_GENERIC,
+};
+
 struct dss_clock_info {
 	/* rates that we get with dividers below */
 	unsigned long fck;
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 2babe7e..00462cd 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -225,12 +225,20 @@ void dsi_bus_lock(struct omap_dss_device *dssdev);
 void dsi_bus_unlock(struct omap_dss_device *dssdev);
 int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
 		int len);
-int dsi_vc_dcs_write_0(struct omap_dss_device *dssdev, int channel,
-		u8 dcs_cmd);
+int dsi_vc_generic_write(struct omap_dss_device *dssdev, int channel, u8 *data,
+		int len);
+int dsi_vc_dcs_write_0(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd);
+int dsi_vc_generic_write_0(struct omap_dss_device *dssdev, int channel);
 int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 		u8 param);
+int dsi_vc_generic_write_1(struct omap_dss_device *dssdev, int channel,
+		u8 param);
+int dsi_vc_generic_write_2(struct omap_dss_device *dssdev, int channel,
+		u8 param1, u8 param2);
 int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
 		u8 *data, int len);
+int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel,
+		u8 *data, int len);
 int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 		u8 *buf, int buflen);
 int dsi_vc_dcs_read_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
-- 
1.7.1


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

* [PATCH 05/10] OMAP: DSS2: DSI: Remove functions dsi_vc_dcs_read_1() and dsi_vc_dcs_read_2()
  2011-08-30 10:51 [PATCH 00/10] OMAP: DSS2: DSI: Initial DSI video mode support Archit Taneja
                   ` (3 preceding siblings ...)
  2011-08-30 10:51 ` [PATCH 04/10] OMAP: DSS2: DSI: Introduce generic write functions Archit Taneja
@ 2011-08-30 10:51 ` Archit Taneja
  2011-08-30 10:51 ` [PATCH 06/10] OMAP: DSS2: DSI: Split dsi_vc_dcs_read() into 2 functions Archit Taneja
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Archit Taneja @ 2011-08-30 10:51 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

Remove functions dsi_vc_dcs_read_1() and dsi_vc_dcs_read_2(), these are used
when the panel is expected to return 1 and 2 bytes respecitvely. This was manily
used for debugging purposes. These functions should be implemented in the panel
driver if needed.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dsi.c |   38 --------------------------------------
 include/video/omapdss.h       |    4 ----
 2 files changed, 0 insertions(+), 42 deletions(-)

diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index bb55889..8251647 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -3307,44 +3307,6 @@ err:
 }
 EXPORT_SYMBOL(dsi_vc_dcs_read);
 
-int dsi_vc_dcs_read_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
-		u8 *data)
-{
-	int r;
-
-	r = dsi_vc_dcs_read(dssdev, channel, dcs_cmd, data, 1);
-
-	if (r < 0)
-		return r;
-
-	if (r != 1)
-		return -EIO;
-
-	return 0;
-}
-EXPORT_SYMBOL(dsi_vc_dcs_read_1);
-
-int dsi_vc_dcs_read_2(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
-		u8 *data1, u8 *data2)
-{
-	u8 buf[2];
-	int r;
-
-	r = dsi_vc_dcs_read(dssdev, channel, dcs_cmd, buf, 2);
-
-	if (r < 0)
-		return r;
-
-	if (r != 2)
-		return -EIO;
-
-	*data1 = buf[0];
-	*data2 = buf[1];
-
-	return 0;
-}
-EXPORT_SYMBOL(dsi_vc_dcs_read_2);
-
 int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
 		u16 len)
 {
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 00462cd..af30e1f 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -241,10 +241,6 @@ int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel,
 		u8 *data, int len);
 int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 		u8 *buf, int buflen);
-int dsi_vc_dcs_read_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
-		u8 *data);
-int dsi_vc_dcs_read_2(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
-		u8 *data1, u8 *data2);
 int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
 		u16 len);
 int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel);
-- 
1.7.1


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

* [PATCH 06/10] OMAP: DSS2: DSI: Split dsi_vc_dcs_read() into 2 functions
  2011-08-30 10:51 [PATCH 00/10] OMAP: DSS2: DSI: Initial DSI video mode support Archit Taneja
                   ` (4 preceding siblings ...)
  2011-08-30 10:51 ` [PATCH 05/10] OMAP: DSS2: DSI: Remove functions dsi_vc_dcs_read_1() and dsi_vc_dcs_read_2() Archit Taneja
@ 2011-08-30 10:51 ` Archit Taneja
  2011-08-30 10:51 ` [PATCH 07/10] OMAP: DSS2: DSI: Introduce generic read functions Archit Taneja
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Archit Taneja @ 2011-08-30 10:51 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

Split dsi_vc_dcs_read() into the functions:
- dsi_vc_dcs_send_read_request(): This is responsible for sending the short
packet command with the read request.
- dsi_vc_dcs_read_rx_fifo(): This parses the DSI RX fifo of the given virtual
channel, identifies the type of data received, and fills a buffer with the data
provided by the panel.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dsi.c |   61 +++++++++++++++++++++++++++++++++--------
 1 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 8251647..c26a914 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -3196,25 +3196,34 @@ int dsi_vc_generic_write_2(struct omap_dss_device *dssdev, int channel,
 }
 EXPORT_SYMBOL(dsi_vc_generic_write_2);
 
-int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
-		u8 *buf, int buflen)
+static int dsi_vc_dcs_send_read_request(struct omap_dss_device *dssdev,
+		int channel, u8 dcs_cmd)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
-	u32 val;
-	u8 dt;
 	int r;
 
 	if (dsi->debug_read)
-		DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, dcs_cmd);
+		DSSDBG("dsi_vc_dcs_send_read_request(ch%d, dcs_cmd %x)\n",
+			channel, dcs_cmd);
 
 	r = dsi_vc_send_short(dsidev, channel, MIPI_DSI_DCS_READ, dcs_cmd, 0);
-	if (r)
-		goto err;
+	if (r) {
+		DSSERR("dsi_vc_dcs_send_read_request(ch %d, cmd 0x%02x)"
+			" failed\n", channel, dcs_cmd);
+		return r;
+	}
 
-	r = dsi_vc_send_bta_sync(dssdev, channel);
-	if (r)
-		goto err;
+	return 0;
+}
+
+static int dsi_vc_dcs_read_rx_fifo(struct platform_device *dsidev, int channel,
+		u8 *buf, int buflen)
+{
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	u32 val;
+	u8 dt;
+	int r;
 
 	/* RX_FIFO_NOT_EMPTY */
 	if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20) == 0) {
@@ -3300,10 +3309,38 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 
 	BUG();
 err:
-	DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n",
-			channel, dcs_cmd);
+	DSSERR("dsi_vc_dcs_read_rx_fifo(ch %d) failed\n", channel);
+
 	return r;
+}
+
+int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
+		u8 *buf, int buflen)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	int r;
+
+	r = dsi_vc_dcs_send_read_request(dssdev, channel, dcs_cmd);
+	if (r)
+		goto err;
 
+	r = dsi_vc_send_bta_sync(dssdev, channel);
+	if (r)
+		goto err;
+
+	r = dsi_vc_dcs_read_rx_fifo(dsidev, channel, buf, buflen);
+	if (r < 0)
+		goto err;
+
+	if (r != buflen) {
+		r = -EIO;
+		goto err;
+	}
+
+	return 0;
+err:
+	DSSERR("dsi_vc_dcs_read(ch %d, cmd 0x%02x) failed\n", channel, dcs_cmd);
+	return r;
 }
 EXPORT_SYMBOL(dsi_vc_dcs_read);
 
-- 
1.7.1


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

* [PATCH 07/10] OMAP: DSS2: DSI: Introduce generic read functions
  2011-08-30 10:51 [PATCH 00/10] OMAP: DSS2: DSI: Initial DSI video mode support Archit Taneja
                   ` (5 preceding siblings ...)
  2011-08-30 10:51 ` [PATCH 06/10] OMAP: DSS2: DSI: Split dsi_vc_dcs_read() into 2 functions Archit Taneja
@ 2011-08-30 10:51 ` Archit Taneja
  2011-08-30 10:51 ` [PATCH 08/10] OMAP: DSS2: Clean up stallmode and io pad mode selection Archit Taneja
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Archit Taneja @ 2011-08-30 10:51 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

Introduce read functions which use generic Processor-to-Peripheral
transaction types. These are needed by some devices which may not support
corresponding DCS commands.

Add function dsi_vc_generic_send_read_request() which can send
a short packet with 0, 1 or 2 bytes of request data and the corresponding
generic data type.

Rename function dsi_vc_dcs_read_rx_fifo() to dsi_vc_read_rx_fifo() and modify
it to take the enum "dss_dsi_content_type" as an argument to use either DCS
or GENERIC Peripheral-to-Processor transaction types while parsing data read
from the device.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dsi.c |  146 ++++++++++++++++++++++++++++++++++++++---
 include/video/omapdss.h       |    6 ++
 2 files changed, 142 insertions(+), 10 deletions(-)

diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index c26a914..20cad1b 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -3217,8 +3217,44 @@ static int dsi_vc_dcs_send_read_request(struct omap_dss_device *dssdev,
 	return 0;
 }
 
-static int dsi_vc_dcs_read_rx_fifo(struct platform_device *dsidev, int channel,
-		u8 *buf, int buflen)
+static int dsi_vc_generic_send_read_request(struct omap_dss_device *dssdev,
+		int channel, u8 *reqdata, int reqlen)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	u16 data;
+	u8 data_type;
+	int r;
+
+	if (dsi->debug_read)
+		DSSDBG("dsi_vc_generic_send_read_request(ch %d, reqlen %d)\n",
+			channel, reqlen);
+
+	if (reqlen == 0) {
+		data_type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM;
+		data = 0;
+	} else if (reqlen == 1) {
+		data_type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
+		data = reqdata[0];
+	} else if (reqlen == 2) {
+		data_type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM;
+		data = reqdata[0] | (reqdata[1] << 8);
+	} else {
+		BUG();
+	}
+
+	r = dsi_vc_send_short(dsidev, channel, data_type, data, 0);
+	if (r) {
+		DSSERR("dsi_vc_generic_send_read_request(ch %d, reqlen %d)"
+			" failed\n", channel, reqlen);
+		return r;
+	}
+
+	return 0;
+}
+
+static int dsi_vc_read_rx_fifo(struct platform_device *dsidev, int channel,
+		u8 *buf, int buflen, enum dss_dsi_content_type type)
 {
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	u32 val;
@@ -3242,10 +3278,14 @@ static int dsi_vc_dcs_read_rx_fifo(struct platform_device *dsidev, int channel,
 		r = -EIO;
 		goto err;
 
-	} else if (dt == MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE) {
+	} else if (dt == (type == DSS_DSI_CONTENT_GENERIC ?
+			MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE :
+			MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE)) {
 		u8 data = FLD_GET(val, 15, 8);
 		if (dsi->debug_read)
-			DSSDBG("\tDCS short response, 1 byte: %02x\n", data);
+			DSSDBG("\t%s short response, 1 byte: %02x\n",
+				type == DSS_DSI_CONTENT_GENERIC ? "GENERIC" :
+				"DCS", data);
 
 		if (buflen < 1) {
 			r = -EIO;
@@ -3255,10 +3295,14 @@ static int dsi_vc_dcs_read_rx_fifo(struct platform_device *dsidev, int channel,
 		buf[0] = data;
 
 		return 1;
-	} else if (dt == MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE) {
+	} else if (dt == (type == DSS_DSI_CONTENT_GENERIC ?
+			MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE :
+			MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE)) {
 		u16 data = FLD_GET(val, 23, 8);
 		if (dsi->debug_read)
-			DSSDBG("\tDCS short response, 2 byte: %04x\n", data);
+			DSSDBG("\t%s short response, 2 byte: %04x\n",
+				type == DSS_DSI_CONTENT_GENERIC ? "GENERIC" :
+				"DCS", data);
 
 		if (buflen < 2) {
 			r = -EIO;
@@ -3269,11 +3313,15 @@ static int dsi_vc_dcs_read_rx_fifo(struct platform_device *dsidev, int channel,
 		buf[1] = (data >> 8) & 0xff;
 
 		return 2;
-	} else if (dt == MIPI_DSI_RX_DCS_LONG_READ_RESPONSE) {
+	} else if (dt == (type == DSS_DSI_CONTENT_GENERIC ?
+			MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE :
+			MIPI_DSI_RX_DCS_LONG_READ_RESPONSE)) {
 		int w;
 		int len = FLD_GET(val, 23, 8);
 		if (dsi->debug_read)
-			DSSDBG("\tDCS long response, len %d\n", len);
+			DSSDBG("\t%s long response, len %d\n",
+				type == DSS_DSI_CONTENT_GENERIC ? "GENERIC" :
+				"DCS", len);
 
 		if (len > buflen) {
 			r = -EIO;
@@ -3309,7 +3357,8 @@ static int dsi_vc_dcs_read_rx_fifo(struct platform_device *dsidev, int channel,
 
 	BUG();
 err:
-	DSSERR("dsi_vc_dcs_read_rx_fifo(ch %d) failed\n", channel);
+	DSSERR("dsi_vc_read_rx_fifo(ch %d type %s) failed\n", channel,
+		type == DSS_DSI_CONTENT_GENERIC ? "GENERIC" : "DCS");
 
 	return r;
 }
@@ -3328,7 +3377,8 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 	if (r)
 		goto err;
 
-	r = dsi_vc_dcs_read_rx_fifo(dsidev, channel, buf, buflen);
+	r = dsi_vc_read_rx_fifo(dsidev, channel, buf, buflen,
+		DSS_DSI_CONTENT_DCS);
 	if (r < 0)
 		goto err;
 
@@ -3344,6 +3394,82 @@ err:
 }
 EXPORT_SYMBOL(dsi_vc_dcs_read);
 
+static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel,
+		u8 *reqdata, int reqlen, u8 *buf, int buflen)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	int r;
+
+	r = dsi_vc_generic_send_read_request(dssdev, channel, reqdata, reqlen);
+	if (r)
+		return r;
+
+	r = dsi_vc_send_bta_sync(dssdev, channel);
+	if (r)
+		return r;
+
+	r = dsi_vc_read_rx_fifo(dsidev, channel, buf, buflen,
+		DSS_DSI_CONTENT_GENERIC);
+	if (r < 0)
+		return r;
+
+	if (r != buflen) {
+		r = -EIO;
+		return r;
+	}
+
+	return 0;
+}
+
+int dsi_vc_generic_read_0(struct omap_dss_device *dssdev, int channel, u8 *buf,
+		int buflen)
+{
+	int r;
+
+	r = dsi_vc_generic_read(dssdev, channel, NULL, 0, buf, buflen);
+	if (r) {
+		DSSERR("dsi_vc_generic_read_0(ch %d) failed\n", channel);
+		return r;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(dsi_vc_generic_read_0);
+
+int dsi_vc_generic_read_1(struct omap_dss_device *dssdev, int channel, u8 param,
+		u8 *buf, int buflen)
+{
+	int r;
+
+	r = dsi_vc_generic_read(dssdev, channel, &param, 1, buf, buflen);
+	if (r) {
+		DSSERR("dsi_vc_generic_read_1(ch %d) failed\n", channel);
+		return r;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(dsi_vc_generic_read_1);
+
+int dsi_vc_generic_read_2(struct omap_dss_device *dssdev, int channel,
+		u8 param1, u8 param2, u8 *buf, int buflen)
+{
+	int r;
+	u8 reqdata[2];
+
+	reqdata[0] = param1;
+	reqdata[1] = param2;
+
+	r = dsi_vc_generic_read(dssdev, channel, reqdata, 2, buf, buflen);
+	if (r) {
+		DSSERR("dsi_vc_generic_read_2(ch %d) failed\n", channel);
+		return r;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(dsi_vc_generic_read_2);
+
 int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
 		u16 len)
 {
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index af30e1f..8c94d95 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -241,6 +241,12 @@ int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel,
 		u8 *data, int len);
 int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd,
 		u8 *buf, int buflen);
+int dsi_vc_generic_read_0(struct omap_dss_device *dssdev, int channel, u8 *buf,
+		int buflen);
+int dsi_vc_generic_read_1(struct omap_dss_device *dssdev, int channel, u8 param,
+		u8 *buf, int buflen);
+int dsi_vc_generic_read_2(struct omap_dss_device *dssdev, int channel,
+		u8 param1, u8 param2, u8 *buf, int buflen);
 int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
 		u16 len);
 int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel);
-- 
1.7.1


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

* [PATCH 08/10] OMAP: DSS2: Clean up stallmode and io pad mode selection
  2011-08-30 10:51 [PATCH 00/10] OMAP: DSS2: DSI: Initial DSI video mode support Archit Taneja
                   ` (6 preceding siblings ...)
  2011-08-30 10:51 ` [PATCH 07/10] OMAP: DSS2: DSI: Introduce generic read functions Archit Taneja
@ 2011-08-30 10:51 ` Archit Taneja
  2011-08-30 10:51 ` [PATCH 09/10] OMAP: DSS2: Create an enum for DSI pixel formats Archit Taneja
  2011-08-30 10:51 ` [PATCH 10/10] OMAP: DSS2: DSI Video mode support Archit Taneja
  9 siblings, 0 replies; 19+ messages in thread
From: Archit Taneja @ 2011-08-30 10:51 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

Split the function dispc_set_parallel_interface_mode() into 2 separate
functions called dispc_mgr_set_io_pad_mode() and dispc_mgr_enable_stallmode().
The current function tries to set 2 different modes(io pad mode and stall mode)
based on a parameter omap_parallel_interface_mode which loosely corresponds to
the panel interface type.

This isn't correct because a) these 2 modes are independent to some extent,
b) we are currently configuring gpout0/gpout1 for DSI panels which is
unnecessary, c) a DSI Video mode panel won't get configured correctly.

Splitting the functions allows the interface driver to set these modes
independently and hence allow more flexibility.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dispc.c |   47 +++++++++++++++++---------------------
 drivers/video/omap2/dss/dpi.c   |    5 ++-
 drivers/video/omap2/dss/dsi.c   |    3 +-
 drivers/video/omap2/dss/dss.h   |   12 +++++-----
 drivers/video/omap2/dss/rfbi.c  |    4 +-
 drivers/video/omap2/dss/sdi.c   |    4 +-
 6 files changed, 35 insertions(+), 40 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index d156a52..4107e0b 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2205,46 +2205,41 @@ void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
 		REG_FLD_MOD(DISPC_CONTROL, code, 9, 8);
 }
 
-void dispc_mgr_set_parallel_interface_mode(enum omap_channel channel,
-		enum omap_parallel_interface_mode mode)
+void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode)
 {
 	u32 l;
-	int stallmode;
-	int gpout0 = 1;
-	int gpout1;
+	int gpout0, gpout1;
 
 	switch (mode) {
-	case OMAP_DSS_PARALLELMODE_BYPASS:
-		stallmode = 0;
-		gpout1 = 1;
+	case DSS_IO_PAD_MODE_RESET:
+		gpout0 = 0;
+		gpout1 = 0;
 		break;
-
-	case OMAP_DSS_PARALLELMODE_RFBI:
-		stallmode = 1;
+	case DSS_IO_PAD_MODE_RFBI:
+		gpout0 = 1;
 		gpout1 = 0;
 		break;
-
-	case OMAP_DSS_PARALLELMODE_DSI:
-		stallmode = 1;
+	case DSS_IO_PAD_MODE_BYPASS:
+		gpout0 = 1;
 		gpout1 = 1;
 		break;
-
 	default:
 		BUG();
 		return;
 	}
 
-	if (channel == OMAP_DSS_CHANNEL_LCD2) {
-		l = dispc_read_reg(DISPC_CONTROL2);
-		l = FLD_MOD(l, stallmode, 11, 11);
-		dispc_write_reg(DISPC_CONTROL2, l);
-	} else {
-		l = dispc_read_reg(DISPC_CONTROL);
-		l = FLD_MOD(l, stallmode, 11, 11);
-		l = FLD_MOD(l, gpout0, 15, 15);
-		l = FLD_MOD(l, gpout1, 16, 16);
-		dispc_write_reg(DISPC_CONTROL, l);
-	}
+	l = dispc_read_reg(DISPC_CONTROL);
+	l = FLD_MOD(l, gpout0, 15, 15);
+	l = FLD_MOD(l, gpout1, 16, 16);
+	dispc_write_reg(DISPC_CONTROL, l);
+}
+
+void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable)
+{
+	if (channel == OMAP_DSS_CHANNEL_LCD2)
+		REG_FLD_MOD(DISPC_CONTROL2, enable, 11, 11);
+	else
+		REG_FLD_MOD(DISPC_CONTROL, enable, 11, 11);
 }
 
 static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 1edc832..483888a 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -166,8 +166,9 @@ static void dpi_basic_init(struct omap_dss_device *dssdev)
 
 	is_tft = (dssdev->panel.config & OMAP_DSS_LCD_TFT) != 0;
 
-	dispc_mgr_set_parallel_interface_mode(dssdev->manager->id,
-			OMAP_DSS_PARALLELMODE_BYPASS);
+	dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS);
+	dispc_mgr_enable_stallmode(dssdev->manager->id, false);
+
 	dispc_mgr_set_lcd_display_type(dssdev->manager->id, is_tft ?
 			OMAP_DSS_LCD_DISPLAY_TFT : OMAP_DSS_LCD_DISPLAY_STN);
 	dispc_mgr_set_tft_data_lines(dssdev->manager->id,
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 20cad1b..c2c2fa7 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4019,8 +4019,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 	dispc_mgr_set_lcd_display_type(dssdev->manager->id,
 			OMAP_DSS_LCD_DISPLAY_TFT);
 
-	dispc_mgr_set_parallel_interface_mode(dssdev->manager->id,
-			OMAP_DSS_PARALLELMODE_DSI);
+	dispc_mgr_enable_stallmode(dssdev->manager->id, true);
 	dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1);
 
 	dispc_mgr_set_tft_data_lines(dssdev->manager->id,
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 3ec8dd7..f4196f5 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -97,10 +97,10 @@ extern unsigned int dss_debug;
 #define FLD_MOD(orig, val, start, end) \
 	(((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
 
-enum omap_parallel_interface_mode {
-	OMAP_DSS_PARALLELMODE_BYPASS,		/* MIPI DPI */
-	OMAP_DSS_PARALLELMODE_RFBI,		/* MIPI DBI */
-	OMAP_DSS_PARALLELMODE_DSI,
+enum dss_io_pad_mode {
+	DSS_IO_PAD_MODE_RESET,
+	DSS_IO_PAD_MODE_RFBI,
+	DSS_IO_PAD_MODE_BYPASS,
 };
 
 enum dss_hdmi_venc_clk_source_select {
@@ -429,8 +429,8 @@ bool dispc_mgr_go_busy(enum omap_channel channel);
 void dispc_mgr_go(enum omap_channel channel);
 void dispc_mgr_enable(enum omap_channel channel, bool enable);
 bool dispc_mgr_is_channel_enabled(enum omap_channel channel);
-void dispc_mgr_set_parallel_interface_mode(enum omap_channel channel,
-		enum omap_parallel_interface_mode mode);
+void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode);
+void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable);
 void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
 void dispc_mgr_set_lcd_display_type(enum omap_channel channel,
 		enum omap_lcd_display_type type);
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index b4a131a..1bd3703 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -868,8 +868,8 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
 	dispc_mgr_set_lcd_display_type(dssdev->manager->id,
 			OMAP_DSS_LCD_DISPLAY_TFT);
 
-	dispc_mgr_set_parallel_interface_mode(dssdev->manager->id,
-			OMAP_DSS_PARALLELMODE_RFBI);
+	dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_RFBI);
+	dispc_mgr_enable_stallmode(dssdev->manager->id, true);
 
 	dispc_mgr_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size);
 
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index e2f35c0..695dc04 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -35,8 +35,8 @@ static struct {
 static void sdi_basic_init(struct omap_dss_device *dssdev)
 
 {
-	dispc_mgr_set_parallel_interface_mode(dssdev->manager->id,
-			OMAP_DSS_PARALLELMODE_BYPASS);
+	dispc_mgr_set_io_pad_mode(DSS_IO_PAD_MODE_BYPASS);
+	dispc_mgr_enable_stallmode(dssdev->manager->id, false);
 
 	dispc_mgr_set_lcd_display_type(dssdev->manager->id,
 			OMAP_DSS_LCD_DISPLAY_TFT);
-- 
1.7.1


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

* [PATCH 09/10] OMAP: DSS2: Create an enum for DSI pixel formats
  2011-08-30 10:51 [PATCH 00/10] OMAP: DSS2: DSI: Initial DSI video mode support Archit Taneja
                   ` (7 preceding siblings ...)
  2011-08-30 10:51 ` [PATCH 08/10] OMAP: DSS2: Clean up stallmode and io pad mode selection Archit Taneja
@ 2011-08-30 10:51 ` Archit Taneja
  2011-08-30 10:51 ` [PATCH 10/10] OMAP: DSS2: DSI Video mode support Archit Taneja
  9 siblings, 0 replies; 19+ messages in thread
From: Archit Taneja @ 2011-08-30 10:51 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

Currently, DSI pixel info is only represented by the pixel size in bits using
the pixel_size parameter in omap_dss_device struct's ctrl member.

This is not sufficient information for DSI video mode usage, as two of the
supported formats(RGB666 loosely packed, and RGB888) have the same pixel
container size, but different data_type values for the video mode packet header.

Create enum "omap_dss_dsi_pixel_format" which describes the pixel data format
the panel is configured for.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/displays/panel-taal.c |    2 +-
 drivers/video/omap2/dss/dsi.c             |   24 ++++++++++++++++++++----
 include/video/omapdss.h                   |    8 ++++++++
 3 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 7675687..ddc696d 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -976,7 +976,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
 
 	dssdev->panel.config = OMAP_DSS_LCD_TFT;
 	dssdev->panel.timings = panel_config->timings;
-	dssdev->ctrl.pixel_size = 24;
+	dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
 
 	td = kzalloc(sizeof(*td), GFP_KERNEL);
 	if (!td) {
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index c2c2fa7..582ae7b 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -422,6 +422,21 @@ static inline int wait_for_bit_change(struct platform_device *dsidev,
 	return value;
 }
 
+static inline u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
+{
+	switch (fmt) {
+	case OMAP_DSS_DSI_FMT_RGB888:
+	case OMAP_DSS_DSI_FMT_RGB666:
+		return 24;
+	case OMAP_DSS_DSI_FMT_RGB666_PACKED:
+		return 18;
+	case OMAP_DSS_DSI_FMT_RGB565:
+		return 16;
+	default:
+		BUG();
+	}
+}
+
 #ifdef DEBUG
 static void dsi_perf_mark_setup(struct platform_device *dsidev)
 {
@@ -438,6 +453,7 @@ static void dsi_perf_mark_start(struct platform_device *dsidev)
 static void dsi_perf_show(struct platform_device *dsidev, const char *name)
 {
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_dss_device *dssdev = dsi->update_region.device;
 	ktime_t t, setup_time, trans_time;
 	u32 total_bytes;
 	u32 setup_us, trans_us, total_us;
@@ -461,7 +477,7 @@ static void dsi_perf_show(struct platform_device *dsidev, const char *name)
 
 	total_bytes = dsi->update_region.w *
 		dsi->update_region.h *
-		dsi->update_region.device->ctrl.pixel_size / 8;
+		dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
 
 	printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
 			"%u bytes, %u kbytes/sec\n",
@@ -3689,7 +3705,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
 	dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true);
 	dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true);
 
-	switch (dssdev->ctrl.pixel_size) {
+	switch (dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt)) {
 	case 16:
 		buswidth = 0;
 		break;
@@ -3814,7 +3830,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
 
 	dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_VP);
 
-	bytespp	= dssdev->ctrl.pixel_size / 8;
+	bytespp	= dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
 	bytespl = w * bytespp;
 	bytespf = bytespl * h;
 
@@ -4023,7 +4039,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 	dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1);
 
 	dispc_mgr_set_tft_data_lines(dssdev->manager->id,
-			dssdev->ctrl.pixel_size);
+			dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt));
 
 	{
 		struct omap_video_timings timings = {
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 8c94d95..1e9a35c 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -129,6 +129,13 @@ enum omap_dss_venc_type {
 	OMAP_DSS_VENC_TYPE_SVIDEO,
 };
 
+enum omap_dss_dsi_pixel_format {
+	OMAP_DSS_DSI_FMT_RGB888,
+	OMAP_DSS_DSI_FMT_RGB666,
+	OMAP_DSS_DSI_FMT_RGB666_PACKED,
+	OMAP_DSS_DSI_FMT_RGB565,
+};
+
 enum omap_dss_dsi_mode {
 	OMAP_DSS_DSI_CMD_MODE = 0,
 	OMAP_DSS_DSI_VIDEO_MODE,
@@ -489,6 +496,7 @@ struct omap_dss_device {
 
 		enum omap_panel_config config;
 
+		enum omap_dss_dsi_pixel_format dsi_pix_fmt;
 		enum omap_dss_dsi_mode dsi_mode;
 	} panel;
 
-- 
1.7.1


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

* [PATCH 10/10] OMAP: DSS2: DSI Video mode support
  2011-08-30 10:51 [PATCH 00/10] OMAP: DSS2: DSI: Initial DSI video mode support Archit Taneja
                   ` (8 preceding siblings ...)
  2011-08-30 10:51 ` [PATCH 09/10] OMAP: DSS2: Create an enum for DSI pixel formats Archit Taneja
@ 2011-08-30 10:51 ` Archit Taneja
  2011-09-01 13:14   ` Tomi Valkeinen
  9 siblings, 1 reply; 19+ messages in thread
From: Archit Taneja @ 2011-08-30 10:51 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, Archit Taneja

Add initial support for DSI video mode panels:
- Add a new structure omap_dss_dsi_videomode_data in the member "panel" in
  omap_dss_device struct. This allows panel driver to configure dsi video_mode
  specific parameters.
- Configure basic DSI video mode timing parameters: HBP, HFP, HSA, VBP, VFP, VSA,
  TL and VACT.
- Configure DSI protocol engine registers for video_mode support.
- Introduce functions dsi_video_mode_enable() and dsi_video_mode_disable() which
  enable/disable video mode for a given virtual channel and a given pixel format
  type.

Things left for later
- Add functions to check for errors in video mode timings provided by panel.
- Configure timing registers required  for command mode interleaving.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dsi.c |  256 ++++++++++++++++++++++++++++++++++++-----
 include/video/omapdss.h       |   32 +++++
 2 files changed, 259 insertions(+), 29 deletions(-)

diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 582ae7b..e3d5c38 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -132,7 +132,7 @@ struct dsi_reg { u16 idx; };
 #define DSI_IRQ_TA_TIMEOUT	(1 << 20)
 #define DSI_IRQ_ERROR_MASK \
 	(DSI_IRQ_HS_TX_TIMEOUT | DSI_IRQ_LP_RX_TIMEOUT | DSI_IRQ_SYNC_LOST | \
-	DSI_IRQ_TA_TIMEOUT)
+	DSI_IRQ_TA_TIMEOUT | DSI_IRQ_SYNC_LOST)
 #define DSI_IRQ_CHANNEL_MASK	0xf
 
 /* Virtual channel interrupts */
@@ -2472,6 +2472,12 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
 
 	dsi_cio_timings(dsidev);
 
+	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+		/* DDR_CLK_ALWAYS_ON */
+		REG_FLD_MOD(dsidev, DSI_CLK_CTRL,
+			dssdev->panel.dsi_vm_data.ddr_clk_always_on, 13, 13);
+	}
+
 	dsi->ulps_enabled = false;
 
 	DSSDBG("CIO init done\n");
@@ -2496,6 +2502,9 @@ static void dsi_cio_uninit(struct omap_dss_device *dssdev)
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
+	/* DDR_CLK_ALWAYS_ON */
+	REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 13, 13);
+
 	dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
 	dsi_disable_scp_clk(dsidev);
 	dsi->disable_pads(dsidev->id, dsi_get_lane_mask(dssdev));
@@ -3683,6 +3692,75 @@ static void dsi_set_hs_tx_timeout(struct platform_device *dsidev,
 			ticks, x4 ? " x4" : "", x16 ? " x16" : "",
 			(total_ticks * 1000) / (fck / 1000 / 1000));
 }
+
+static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	int num_line_buffers;
+
+	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+		int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
+		unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
+		struct omap_video_timings *timings = &dssdev->panel.timings;
+		/*
+		 * Don't use line buffers if width is greater than the video
+		 * port's line buffer size
+		 */
+		if (line_buf_size <= timings->x_res * bpp / 8)
+			num_line_buffers = 0;
+		else
+			num_line_buffers = 2;
+	} else {
+		/* Use maximum number of line buffers in command mode */
+		num_line_buffers = 2;
+	}
+
+	/* LINE_BUFFER */
+	REG_FLD_MOD(dsidev, DSI_CTRL, num_line_buffers, 13, 12);
+}
+
+static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	int de_pol = dssdev->panel.dsi_vm_data.vp_de_pol;
+	int hsync_pol = dssdev->panel.dsi_vm_data.vp_hsync_pol;
+	int vsync_pol = dssdev->panel.dsi_vm_data.vp_vsync_pol;
+	bool vsync_end = dssdev->panel.dsi_vm_data.vp_vsync_end;
+	bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
+	u32 r;
+
+	r = dsi_read_reg(dsidev, DSI_CTRL);
+	r = FLD_MOD(r, de_pol, 9, 9);		/* VP_DE_POL */
+	r = FLD_MOD(r, hsync_pol, 10, 10);	/* VP_HSYNC_POL */
+	r = FLD_MOD(r, vsync_pol, 11, 11);	/* VP_VSYNC_POL */
+	r = FLD_MOD(r, 1, 15, 15);		/* VP_VSYNC_START */
+	r = FLD_MOD(r, vsync_end, 16, 16);	/* VP_VSYNC_END */
+	r = FLD_MOD(r, 1, 17, 17);		/* VP_HSYNC_START */
+	r = FLD_MOD(r, hsync_end, 18, 18);	/* VP_HSYNC_END */
+	dsi_write_reg(dsidev, DSI_CTRL, r);
+}
+
+static void dsi_config_blanking_modes(struct omap_dss_device *dssdev)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	int blanking_mode = dssdev->panel.dsi_vm_data.blanking_mode;
+	int hfp_blanking_mode = dssdev->panel.dsi_vm_data.hfp_blanking_mode;
+	int hbp_blanking_mode = dssdev->panel.dsi_vm_data.hbp_blanking_mode;
+	int hsa_blanking_mode = dssdev->panel.dsi_vm_data.hsa_blanking_mode;
+	u32 r;
+
+	/*
+	 * 0 = TX FIFO packets sent or LPS in corresponding blanking periods
+	 * 1 = Long blanking packets are sent in corresponding blanking periods
+	 */
+	r = dsi_read_reg(dsidev, DSI_CTRL);
+	r = FLD_MOD(r, blanking_mode, 20, 20);		/* BLANKING_MODE */
+	r = FLD_MOD(r, hfp_blanking_mode, 21, 21);	/* HFP_BLANKING */
+	r = FLD_MOD(r, hbp_blanking_mode, 22, 22);	/* HBP_BLANKING */
+	r = FLD_MOD(r, hsa_blanking_mode, 23, 23);	/* HSA_BLANKING */
+	dsi_write_reg(dsidev, DSI_CTRL, r);
+}
+
 static int dsi_proto_config(struct omap_dss_device *dssdev)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -3726,7 +3804,6 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
 	r = FLD_MOD(r, 1, 4, 4);	/* VP_CLK_RATIO, always 1, see errata*/
 	r = FLD_MOD(r, buswidth, 7, 6); /* VP_DATA_BUS_WIDTH */
 	r = FLD_MOD(r, 0, 8, 8);	/* VP_CLK_POL */
-	r = FLD_MOD(r, 2, 13, 12);	/* LINE_BUFFER, 2 lines */
 	r = FLD_MOD(r, 1, 14, 14);	/* TRIGGER_RESET_MODE */
 	r = FLD_MOD(r, 1, 19, 19);	/* EOT_ENABLE */
 	if (!dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) {
@@ -3737,6 +3814,13 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
 
 	dsi_write_reg(dsidev, DSI_CTRL, r);
 
+	dsi_config_vp_num_line_buffers(dssdev);
+
+	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+		dsi_config_vp_sync_events(dssdev);
+		dsi_config_blanking_modes(dssdev);
+	}
+
 	dsi_vc_initial_config(dsidev, 0);
 	dsi_vc_initial_config(dsidev, 1);
 	dsi_vc_initial_config(dsidev, 2);
@@ -3755,6 +3839,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
 	unsigned ddr_clk_pre, ddr_clk_post;
 	unsigned enter_hs_mode_lat, exit_hs_mode_lat;
 	unsigned ths_eot;
+	int ndl = dsi_get_num_data_lanes_dssdev(dssdev);
 	u32 r;
 
 	r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0);
@@ -3777,7 +3862,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
 	/* min 60ns + 52*UI */
 	tclk_post = ns2ddr(dsidev, 60) + 26;
 
-	ths_eot = DIV_ROUND_UP(4, dsi_get_num_data_lanes_dssdev(dssdev));
+	ths_eot = DIV_ROUND_UP(4, ndl);
 
 	ddr_clk_pre = DIV_ROUND_UP(tclk_pre + tlpx + tclk_zero + tclk_prepare,
 			4);
@@ -3807,8 +3892,115 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
 
 	DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n",
 			enter_hs_mode_lat, exit_hs_mode_lat);
+
+	 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+		/* TODO: Implement a video mode check_timings function */
+		int hsa = dssdev->panel.dsi_vm_data.hsa;
+		int hfp = dssdev->panel.dsi_vm_data.hfp;
+		int hbp = dssdev->panel.dsi_vm_data.hbp;
+		int vsa = dssdev->panel.dsi_vm_data.vsa;
+		int vfp = dssdev->panel.dsi_vm_data.vfp;
+		int vbp = dssdev->panel.dsi_vm_data.vbp;
+		int window_sync = dssdev->panel.dsi_vm_data.window_sync;
+		bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
+		struct omap_video_timings *timings = &dssdev->panel.timings;
+		int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
+		int tl, t_he, width_bytes;
+
+		t_he = hsync_end ?
+			((hsa == 0 && ndl == 3) ? 1 : DIV_ROUND_UP(4, ndl)) : 0;
+
+		width_bytes = DIV_ROUND_UP(timings->x_res * bpp, 8);
+
+		/* TL = t_HS + HSA + t_HE + HFP + ceil((WC + 6) / NDL) + HBP */
+		tl = DIV_ROUND_UP(4, ndl) + (hsync_end ? hsa : 0) + t_he + hfp +
+			DIV_ROUND_UP(width_bytes + 6, ndl) + hbp;
+
+		DSSDBG("HBP: %d, HFP: %d, HSA: %d, TL: %d TXBYTECLKHS\n", hbp,
+			hfp, hsync_end ? hsa : 0, tl);
+		DSSDBG("VBP: %d, VFP: %d, VSA: %d, VACT: %d lines\n", vbp, vfp,
+			vsa, timings->y_res);
+
+		r = dsi_read_reg(dsidev, DSI_VM_TIMING1);
+		r = FLD_MOD(r, hbp, 11, 0);	/* HBP */
+		r = FLD_MOD(r, hfp, 23, 12);	/* HFP */
+		r = FLD_MOD(r, hsync_end ? hsa : 0, 31, 24);	/* HSA */
+		dsi_write_reg(dsidev, DSI_VM_TIMING1, r);
+
+		r = dsi_read_reg(dsidev, DSI_VM_TIMING2);
+		r = FLD_MOD(r, vbp, 7, 0);	/* VBP */
+		r = FLD_MOD(r, vfp, 15, 8);	/* VFP */
+		r = FLD_MOD(r, vsa, 23, 16);	/* VSA */
+		r = FLD_MOD(r, window_sync, 27, 24);	/* WINDOW_SYNC */
+		dsi_write_reg(dsidev, DSI_VM_TIMING2, r);
+
+		r = dsi_read_reg(dsidev, DSI_VM_TIMING3);
+		r = FLD_MOD(r, timings->y_res, 14, 0);	/* VACT */
+		r = FLD_MOD(r, tl, 31, 16);		/* TL */
+		dsi_write_reg(dsidev, DSI_VM_TIMING3, r);
+	}
 }
 
+int dsi_video_mode_enable(struct omap_dss_device *dssdev, int channel)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
+	u8 data_type;
+	u16 word_count;
+
+	switch (dssdev->panel.dsi_pix_fmt) {
+	case OMAP_DSS_DSI_FMT_RGB888:
+		data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
+		break;
+	case OMAP_DSS_DSI_FMT_RGB666:
+		data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
+		break;
+	case OMAP_DSS_DSI_FMT_RGB666_PACKED:
+		data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18;
+		break;
+	case OMAP_DSS_DSI_FMT_RGB565:
+		data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
+		break;
+	default:
+		BUG();
+	};
+
+	dsi_if_enable(dsidev, false);
+	dsi_vc_enable(dsidev, channel, false);
+
+	/* MODE, 1 = video mode */
+	REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4);
+
+	word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8);
+
+	dsi_vc_write_long_header(dsidev, channel, data_type, word_count, 0);
+
+	dsi_vc_enable(dsidev, channel, true);
+	dsi_if_enable(dsidev, true);
+
+	dssdev->manager->enable(dssdev->manager);
+
+	return 0;
+}
+EXPORT_SYMBOL(dsi_video_mode_enable);
+
+void dsi_video_mode_disable(struct omap_dss_device *dssdev, int channel)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+
+	dsi_if_enable(dsidev, false);
+	dsi_vc_enable(dsidev, channel, false);
+
+	/* MODE, 0 = command mode */
+	REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 4, 4);
+
+	dsi_vc_enable(dsidev, channel, true);
+	dsi_if_enable(dsidev, true);
+
+	dssdev->manager->disable(dssdev->manager);
+}
+EXPORT_SYMBOL(dsi_video_mode_disable);
+
 static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
 		u16 x, u16 y, u16 w, u16 h)
 {
@@ -4020,28 +4212,9 @@ EXPORT_SYMBOL(omap_dsi_update);
 static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 {
 	int r;
-	u32 irq;
-
-	irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
-		DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
-
-	r = omap_dispc_register_isr(dsi_framedone_irq_callback, (void *) dssdev,
-			irq);
-	if (r) {
-		DSSERR("can't get FRAMEDONE irq\n");
-		return r;
-	}
-
-	dispc_mgr_set_lcd_display_type(dssdev->manager->id,
-			OMAP_DSS_LCD_DISPLAY_TFT);
-
-	dispc_mgr_enable_stallmode(dssdev->manager->id, true);
-	dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1);
-
-	dispc_mgr_set_tft_data_lines(dssdev->manager->id,
-			dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt));
 
-	{
+	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
+		u32 irq;
 		struct omap_video_timings timings = {
 			.hsw		= 1,
 			.hfp		= 1,
@@ -4051,21 +4224,46 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 			.vbp		= 0,
 		};
 
+		irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
+			DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
+
+		r = omap_dispc_register_isr(dsi_framedone_irq_callback,
+			(void *) dssdev, irq);
+		if (r) {
+			DSSERR("can't get FRAMEDONE irq\n");
+			return r;
+		}
+
+		dispc_mgr_enable_stallmode(dssdev->manager->id, true);
+		dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 1);
+
 		dispc_mgr_set_lcd_timings(dssdev->manager->id, &timings);
+	} else {
+		dispc_mgr_enable_stallmode(dssdev->manager->id, false);
+		dispc_mgr_enable_fifohandcheck(dssdev->manager->id, 0);
+
+		dispc_mgr_set_lcd_timings(dssdev->manager->id,
+			&dssdev->panel.timings);
 	}
 
+		dispc_mgr_set_lcd_display_type(dssdev->manager->id,
+			OMAP_DSS_LCD_DISPLAY_TFT);
+		dispc_mgr_set_tft_data_lines(dssdev->manager->id,
+			dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt));
 	return 0;
 }
 
 static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
 {
-	u32 irq;
+	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
+		u32 irq;
 
-	irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
-		DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
+		irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
+			DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
 
-	omap_dispc_unregister_isr(dsi_framedone_irq_callback, (void *) dssdev,
-			irq);
+		omap_dispc_unregister_isr(dsi_framedone_irq_callback,
+			(void *) dssdev, irq);
+	}
 }
 
 static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 1e9a35c..c462ed0 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -228,6 +228,35 @@ void rfbi_bus_lock(void);
 void rfbi_bus_unlock(void);
 
 /* DSI */
+
+struct omap_dss_dsi_videomode_data {
+	/* DSI video mode blanking data */
+	/* Unit: byte clock cycles */
+	u16 hsa;
+	u16 hfp;
+	u16 hbp;
+	/* Unit: line clocks */
+	u16 vsa;
+	u16 vfp;
+	u16 vbp;
+
+	/* DSI blanking modes */
+	int blanking_mode;
+	int hsa_blanking_mode;
+	int hbp_blanking_mode;
+	int hfp_blanking_mode;
+
+	/* Video port sync events */
+	int vp_de_pol;
+	int vp_hsync_pol;
+	int vp_vsync_pol;
+	bool vp_vsync_end;
+	bool vp_hsync_end;
+
+	bool ddr_clk_always_on;
+	int window_sync;
+};
+
 void dsi_bus_lock(struct omap_dss_device *dssdev);
 void dsi_bus_unlock(struct omap_dss_device *dssdev);
 int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data,
@@ -258,6 +287,8 @@ int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
 		u16 len);
 int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel);
 int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel);
+int dsi_video_mode_enable(struct omap_dss_device *dssdev, int channel);
+void dsi_video_mode_disable(struct omap_dss_device *dssdev, int channel);
 
 /* Board specific data */
 struct omap_dss_board_info {
@@ -498,6 +529,7 @@ struct omap_dss_device {
 
 		enum omap_dss_dsi_pixel_format dsi_pix_fmt;
 		enum omap_dss_dsi_mode dsi_mode;
+		struct omap_dss_dsi_videomode_data dsi_vm_data;
 	} panel;
 
 	struct {
-- 
1.7.1


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

* Re: [PATCH 10/10] OMAP: DSS2: DSI Video mode support
  2011-08-30 10:51 ` [PATCH 10/10] OMAP: DSS2: DSI Video mode support Archit Taneja
@ 2011-09-01 13:14   ` Tomi Valkeinen
  2011-09-02  5:15     ` Archit Taneja
  0 siblings, 1 reply; 19+ messages in thread
From: Tomi Valkeinen @ 2011-09-01 13:14 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-omap

On Tue, 2011-08-30 at 16:21 +0530, Archit Taneja wrote:
> Add initial support for DSI video mode panels:
> - Add a new structure omap_dss_dsi_videomode_data in the member "panel" in
>   omap_dss_device struct. This allows panel driver to configure dsi video_mode
>   specific parameters.
> - Configure basic DSI video mode timing parameters: HBP, HFP, HSA, VBP, VFP, VSA,
>   TL and VACT.
> - Configure DSI protocol engine registers for video_mode support.
> - Introduce functions dsi_video_mode_enable() and dsi_video_mode_disable() which
>   enable/disable video mode for a given virtual channel and a given pixel format
>   type.
> 
> Things left for later
> - Add functions to check for errors in video mode timings provided by panel.
> - Configure timing registers required  for command mode interleaving.
> 
> Signed-off-by: Archit Taneja <archit@ti.com>
> ---
>  drivers/video/omap2/dss/dsi.c |  256 ++++++++++++++++++++++++++++++++++++-----
>  include/video/omapdss.h       |   32 +++++
>  2 files changed, 259 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
> index 582ae7b..e3d5c38 100644
> --- a/drivers/video/omap2/dss/dsi.c
> +++ b/drivers/video/omap2/dss/dsi.c
> @@ -132,7 +132,7 @@ struct dsi_reg { u16 idx; };
>  #define DSI_IRQ_TA_TIMEOUT	(1 << 20)
>  #define DSI_IRQ_ERROR_MASK \
>  	(DSI_IRQ_HS_TX_TIMEOUT | DSI_IRQ_LP_RX_TIMEOUT | DSI_IRQ_SYNC_LOST | \
> -	DSI_IRQ_TA_TIMEOUT)
> +	DSI_IRQ_TA_TIMEOUT | DSI_IRQ_SYNC_LOST)
>  #define DSI_IRQ_CHANNEL_MASK	0xf
>  
>  /* Virtual channel interrupts */
> @@ -2472,6 +2472,12 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
>  
>  	dsi_cio_timings(dsidev);
>  
> +	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
> +		/* DDR_CLK_ALWAYS_ON */
> +		REG_FLD_MOD(dsidev, DSI_CLK_CTRL,
> +			dssdev->panel.dsi_vm_data.ddr_clk_always_on, 13, 13);
> +	}
> +

For the DDR clock to start, you need to send a null packet, don't you?

 Tomi



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

* Re: [PATCH 10/10] OMAP: DSS2: DSI Video mode support
  2011-09-01 13:14   ` Tomi Valkeinen
@ 2011-09-02  5:15     ` Archit Taneja
  2011-09-02  5:32       ` Tomi Valkeinen
  0 siblings, 1 reply; 19+ messages in thread
From: Archit Taneja @ 2011-09-02  5:15 UTC (permalink / raw)
  To: Valkeinen, Tomi; +Cc: linux-omap

Hi,

On Thursday 01 September 2011 06:44 PM, Valkeinen, Tomi wrote:
> On Tue, 2011-08-30 at 16:21 +0530, Archit Taneja wrote:
>> Add initial support for DSI video mode panels:
>> - Add a new structure omap_dss_dsi_videomode_data in the member "panel" in
>>    omap_dss_device struct. This allows panel driver to configure dsi video_mode
>>    specific parameters.
>> - Configure basic DSI video mode timing parameters: HBP, HFP, HSA, VBP, VFP, VSA,
>>    TL and VACT.
>> - Configure DSI protocol engine registers for video_mode support.
>> - Introduce functions dsi_video_mode_enable() and dsi_video_mode_disable() which
>>    enable/disable video mode for a given virtual channel and a given pixel format
>>    type.
>>
>> Things left for later
>> - Add functions to check for errors in video mode timings provided by panel.
>> - Configure timing registers required  for command mode interleaving.
>>
>> Signed-off-by: Archit Taneja<archit@ti.com>
>> ---
>>   drivers/video/omap2/dss/dsi.c |  256 ++++++++++++++++++++++++++++++++++++-----
>>   include/video/omapdss.h       |   32 +++++
>>   2 files changed, 259 insertions(+), 29 deletions(-)
>>
>> diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
>> index 582ae7b..e3d5c38 100644
>> --- a/drivers/video/omap2/dss/dsi.c
>> +++ b/drivers/video/omap2/dss/dsi.c
>> @@ -132,7 +132,7 @@ struct dsi_reg { u16 idx; };
>>   #define DSI_IRQ_TA_TIMEOUT	(1<<  20)
>>   #define DSI_IRQ_ERROR_MASK \
>>   	(DSI_IRQ_HS_TX_TIMEOUT | DSI_IRQ_LP_RX_TIMEOUT | DSI_IRQ_SYNC_LOST | \
>> -	DSI_IRQ_TA_TIMEOUT)
>> +	DSI_IRQ_TA_TIMEOUT | DSI_IRQ_SYNC_LOST)
>>   #define DSI_IRQ_CHANNEL_MASK	0xf
>>
>>   /* Virtual channel interrupts */
>> @@ -2472,6 +2472,12 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
>>
>>   	dsi_cio_timings(dsidev);
>>
>> +	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
>> +		/* DDR_CLK_ALWAYS_ON */
>> +		REG_FLD_MOD(dsidev, DSI_CLK_CTRL,
>> +			dssdev->panel.dsi_vm_data.ddr_clk_always_on, 13, 13);
>> +	}
>> +
>
> For the DDR clock to start, you need to send a null packet, don't you?

Yes, we have to send a null packet, but that is for the case when DDR 
clock is required by the panel to function properly. Hence we need to 
start the DDR clock right at the beginning(before we start sending 
DCS/generic commands to configure the panel).

The panel driver may set DDR_CLK_ALWAYS_ON even if it has its own 
internal clock to function. In that case, we don't need it to be enabled 
right at the beginning, i.e, when we send DCS commands to configure the 
panel. In this case, the signal TxRequestHS will be asserted later on 
when we enable video mode for a VC, and that will start the DDR clock.

I had left out the "sending null packet" part as I think its a more 
specific case. Setting DDR_CLK_ALWAYS_ON affects timing calculations, 
that is why I added it as a configurable parameter for the panel driver.

Archit

>
>   Tomi
>
>


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

* Re: [PATCH 10/10] OMAP: DSS2: DSI Video mode support
  2011-09-02  5:15     ` Archit Taneja
@ 2011-09-02  5:32       ` Tomi Valkeinen
  2011-09-02  6:13         ` Archit Taneja
  0 siblings, 1 reply; 19+ messages in thread
From: Tomi Valkeinen @ 2011-09-02  5:32 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-omap

On Fri, 2011-09-02 at 10:45 +0530, Archit Taneja wrote:
> Hi,
> 
> On Thursday 01 September 2011 06:44 PM, Valkeinen, Tomi wrote:
> > On Tue, 2011-08-30 at 16:21 +0530, Archit Taneja wrote:
> >> Add initial support for DSI video mode panels:
> >> - Add a new structure omap_dss_dsi_videomode_data in the member "panel" in
> >>    omap_dss_device struct. This allows panel driver to configure dsi video_mode
> >>    specific parameters.
> >> - Configure basic DSI video mode timing parameters: HBP, HFP, HSA, VBP, VFP, VSA,
> >>    TL and VACT.
> >> - Configure DSI protocol engine registers for video_mode support.
> >> - Introduce functions dsi_video_mode_enable() and dsi_video_mode_disable() which
> >>    enable/disable video mode for a given virtual channel and a given pixel format
> >>    type.
> >>
> >> Things left for later
> >> - Add functions to check for errors in video mode timings provided by panel.
> >> - Configure timing registers required  for command mode interleaving.
> >>
> >> Signed-off-by: Archit Taneja<archit@ti.com>
> >> ---
> >>   drivers/video/omap2/dss/dsi.c |  256 ++++++++++++++++++++++++++++++++++++-----
> >>   include/video/omapdss.h       |   32 +++++
> >>   2 files changed, 259 insertions(+), 29 deletions(-)
> >>
> >> diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
> >> index 582ae7b..e3d5c38 100644
> >> --- a/drivers/video/omap2/dss/dsi.c
> >> +++ b/drivers/video/omap2/dss/dsi.c
> >> @@ -132,7 +132,7 @@ struct dsi_reg { u16 idx; };
> >>   #define DSI_IRQ_TA_TIMEOUT	(1<<  20)
> >>   #define DSI_IRQ_ERROR_MASK \
> >>   	(DSI_IRQ_HS_TX_TIMEOUT | DSI_IRQ_LP_RX_TIMEOUT | DSI_IRQ_SYNC_LOST | \
> >> -	DSI_IRQ_TA_TIMEOUT)
> >> +	DSI_IRQ_TA_TIMEOUT | DSI_IRQ_SYNC_LOST)
> >>   #define DSI_IRQ_CHANNEL_MASK	0xf
> >>
> >>   /* Virtual channel interrupts */
> >> @@ -2472,6 +2472,12 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
> >>
> >>   	dsi_cio_timings(dsidev);
> >>
> >> +	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
> >> +		/* DDR_CLK_ALWAYS_ON */
> >> +		REG_FLD_MOD(dsidev, DSI_CLK_CTRL,
> >> +			dssdev->panel.dsi_vm_data.ddr_clk_always_on, 13, 13);
> >> +	}
> >> +
> >
> > For the DDR clock to start, you need to send a null packet, don't you?
> 
> Yes, we have to send a null packet, but that is for the case when DDR 
> clock is required by the panel to function properly. Hence we need to 
> start the DDR clock right at the beginning(before we start sending 
> DCS/generic commands to configure the panel).
> 
> The panel driver may set DDR_CLK_ALWAYS_ON even if it has its own 
> internal clock to function. In that case, we don't need it to be enabled 
> right at the beginning, i.e, when we send DCS commands to configure the 
> panel. In this case, the signal TxRequestHS will be asserted later on 
> when we enable video mode for a VC, and that will start the DDR clock.

Why would the panel need DDR_CLK_ALWAYS_ON if it has an another fclk?
I'm not that familiar with video mode, but somehow it would sound
logical that if the panel wants DDR clock to be always on, it should be
started right from the beginning. And if the panel doesn't need DDR
clock to be always on, there's no need to even set DDR_CLK_ALWAYS_ON.

> I had left out the "sending null packet" part as I think its a more 
> specific case. Setting DDR_CLK_ALWAYS_ON affects timing calculations, 
> that is why I added it as a configurable parameter for the panel driver.

Ok. But your patches handle the calculations, don't they?

Sending a null packet to start the DDR clk is rather OMAP specific
internal thing, so I don't want to require the panel driver to need to
know that it must send a null packet to start the clock. So if the ddr
clk is not started automatically, I think we should have a function to
do that (dsi_start_ddr_clk or whatever), which will then send the null
packet (and perhaps return an error if DDR_CLK_ALWAYS_ON is not set,
dunno...).

 Tomi



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

* Re: [PATCH 10/10] OMAP: DSS2: DSI Video mode support
  2011-09-02  5:32       ` Tomi Valkeinen
@ 2011-09-02  6:13         ` Archit Taneja
  2011-09-02  7:55           ` Tomi Valkeinen
  0 siblings, 1 reply; 19+ messages in thread
From: Archit Taneja @ 2011-09-02  6:13 UTC (permalink / raw)
  To: Valkeinen, Tomi; +Cc: linux-omap

On Friday 02 September 2011 11:02 AM, Valkeinen, Tomi wrote:
> On Fri, 2011-09-02 at 10:45 +0530, Archit Taneja wrote:
>> Hi,
>>
>> On Thursday 01 September 2011 06:44 PM, Valkeinen, Tomi wrote:
>>> On Tue, 2011-08-30 at 16:21 +0530, Archit Taneja wrote:
>>>> Add initial support for DSI video mode panels:
>>>> - Add a new structure omap_dss_dsi_videomode_data in the member "panel" in
>>>>     omap_dss_device struct. This allows panel driver to configure dsi video_mode
>>>>     specific parameters.
>>>> - Configure basic DSI video mode timing parameters: HBP, HFP, HSA, VBP, VFP, VSA,
>>>>     TL and VACT.
>>>> - Configure DSI protocol engine registers for video_mode support.
>>>> - Introduce functions dsi_video_mode_enable() and dsi_video_mode_disable() which
>>>>     enable/disable video mode for a given virtual channel and a given pixel format
>>>>     type.
>>>>
>>>> Things left for later
>>>> - Add functions to check for errors in video mode timings provided by panel.
>>>> - Configure timing registers required  for command mode interleaving.
>>>>
>>>> Signed-off-by: Archit Taneja<archit@ti.com>
>>>> ---
>>>>    drivers/video/omap2/dss/dsi.c |  256 ++++++++++++++++++++++++++++++++++++-----
>>>>    include/video/omapdss.h       |   32 +++++
>>>>    2 files changed, 259 insertions(+), 29 deletions(-)
>>>>
>>>> diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
>>>> index 582ae7b..e3d5c38 100644
>>>> --- a/drivers/video/omap2/dss/dsi.c
>>>> +++ b/drivers/video/omap2/dss/dsi.c
>>>> @@ -132,7 +132,7 @@ struct dsi_reg { u16 idx; };
>>>>    #define DSI_IRQ_TA_TIMEOUT	(1<<   20)
>>>>    #define DSI_IRQ_ERROR_MASK \
>>>>    	(DSI_IRQ_HS_TX_TIMEOUT | DSI_IRQ_LP_RX_TIMEOUT | DSI_IRQ_SYNC_LOST | \
>>>> -	DSI_IRQ_TA_TIMEOUT)
>>>> +	DSI_IRQ_TA_TIMEOUT | DSI_IRQ_SYNC_LOST)
>>>>    #define DSI_IRQ_CHANNEL_MASK	0xf
>>>>
>>>>    /* Virtual channel interrupts */
>>>> @@ -2472,6 +2472,12 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
>>>>
>>>>    	dsi_cio_timings(dsidev);
>>>>
>>>> +	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
>>>> +		/* DDR_CLK_ALWAYS_ON */
>>>> +		REG_FLD_MOD(dsidev, DSI_CLK_CTRL,
>>>> +			dssdev->panel.dsi_vm_data.ddr_clk_always_on, 13, 13);
>>>> +	}
>>>> +
>>>
>>> For the DDR clock to start, you need to send a null packet, don't you?
>>
>> Yes, we have to send a null packet, but that is for the case when DDR
>> clock is required by the panel to function properly. Hence we need to
>> start the DDR clock right at the beginning(before we start sending
>> DCS/generic commands to configure the panel).
>>
>> The panel driver may set DDR_CLK_ALWAYS_ON even if it has its own
>> internal clock to function. In that case, we don't need it to be enabled
>> right at the beginning, i.e, when we send DCS commands to configure the
>> panel. In this case, the signal TxRequestHS will be asserted later on
>> when we enable video mode for a VC, and that will start the DDR clock.
>
> Why would the panel need DDR_CLK_ALWAYS_ON if it has an another fclk?
> I'm not that familiar with video mode, but somehow it would sound
> logical that if the panel wants DDR clock to be always on, it should be
> started right from the beginning. And if the panel doesn't need DDR
> clock to be always on, there's no need to even set DDR_CLK_ALWAYS_ON.

I'm not totally sure about this to be honest, but I have seen a customer 
panel which works on its internal clocks, but they may get disabled in 
certain scenarios, and at that point might need the host's HS clock. 
I'll try to find out more about this, I'm not totally clear about it myself.

>
>> I had left out the "sending null packet" part as I think its a more
>> specific case. Setting DDR_CLK_ALWAYS_ON affects timing calculations,
>> that is why I added it as a configurable parameter for the panel driver.
>
> Ok. But your patches handle the calculations, don't they?

Well, not really. DDR_CLK_ALWAYS_ON being set/not set is used in the 
calculation of the final PLL divider values, and the horizontal/vertical 
timings for DISPC and DSI. Since these are all already provided by the 
panel driver, we don't need to do any calculations.

I was considering to create a check_video_mode_timings function for 
later. That would validate if the timings calculated are correct with 
DDR_CLK_ALWAYS_ON set.

>
> Sending a null packet to start the DDR clk is rather OMAP specific
> internal thing, so I don't want to require the panel driver to need to
> know that it must send a null packet to start the clock. So if the ddr
> clk is not started automatically, I think we should have a function to
> do that (dsi_start_ddr_clk or whatever), which will then send the null
> packet (and perhaps return an error if DDR_CLK_ALWAYS_ON is not set,
> dunno...).

Okay, If we can confirm that a panel asks for DDR_CLK_ALWAYS_ON mainly 
because it doesn't have its own fclk, then the dsi driver surely needs 
to start the DDR clock by sending a NULL packet.

If this is to be done, one thing that has to be thought of is:

- We need one of the requested VC's to be in HS mode for this. Do we 
enable HS for a VC in the dsi driver itself? Currently, its the job of 
the panel driver to enable HSmode for a VC. Is this a clean approach?

Archit

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

* Re: [PATCH 10/10] OMAP: DSS2: DSI Video mode support
  2011-09-02  6:13         ` Archit Taneja
@ 2011-09-02  7:55           ` Tomi Valkeinen
  2011-09-05  5:52             ` Archit Taneja
  0 siblings, 1 reply; 19+ messages in thread
From: Tomi Valkeinen @ 2011-09-02  7:55 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-omap

On Fri, 2011-09-02 at 11:43 +0530, Archit Taneja wrote:
> > Sending a null packet to start the DDR clk is rather OMAP specific
> > internal thing, so I don't want to require the panel driver to need
> to
> > know that it must send a null packet to start the clock. So if the
> ddr
> > clk is not started automatically, I think we should have a function
> to
> > do that (dsi_start_ddr_clk or whatever), which will then send the
> null
> > packet (and perhaps return an error if DDR_CLK_ALWAYS_ON is not set,
> > dunno...).
> 
> Okay, If we can confirm that a panel asks for DDR_CLK_ALWAYS_ON
> mainly 
> because it doesn't have its own fclk, then the dsi driver surely
> needs 
> to start the DDR clock by sending a NULL packet.
> 
> If this is to be done, one thing that has to be thought of is:
> 
> - We need one of the requested VC's to be in HS mode for this. Do we 
> enable HS for a VC in the dsi driver itself? Currently, its the job
> of 
> the panel driver to enable HSmode for a VC. Is this a clean approach? 

I have to say I don't have any idea what would be the best approach...

What comes to my mind is that the DSI driver could automatically send
the null packet, when:

a) ddr_clk_always_on is set
b) a channel is changed to HS and enabled (I guess it needs to be
enabled also, does it?)

Well, we do seem to enable all VCs at init phase (which, thinking about
it, sounds a bit odd), so in practice we would just need to handle the
omapdss_dsi_vc_enable_hs() case.

 Tomi



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

* Re: [PATCH 10/10] OMAP: DSS2: DSI Video mode support
  2011-09-02  7:55           ` Tomi Valkeinen
@ 2011-09-05  5:52             ` Archit Taneja
  2011-09-05  6:52               ` Tomi Valkeinen
  0 siblings, 1 reply; 19+ messages in thread
From: Archit Taneja @ 2011-09-05  5:52 UTC (permalink / raw)
  To: Valkeinen, Tomi; +Cc: linux-omap

On Friday 02 September 2011 01:25 PM, Valkeinen, Tomi wrote:
> On Fri, 2011-09-02 at 11:43 +0530, Archit Taneja wrote:
>>> Sending a null packet to start the DDR clk is rather OMAP specific
>>> internal thing, so I don't want to require the panel driver to need
>> to
>>> know that it must send a null packet to start the clock. So if the
>> ddr
>>> clk is not started automatically, I think we should have a function
>> to
>>> do that (dsi_start_ddr_clk or whatever), which will then send the
>> null
>>> packet (and perhaps return an error if DDR_CLK_ALWAYS_ON is not set,
>>> dunno...).
>>
>> Okay, If we can confirm that a panel asks for DDR_CLK_ALWAYS_ON
>> mainly
>> because it doesn't have its own fclk, then the dsi driver surely
>> needs
>> to start the DDR clock by sending a NULL packet.
>>
>> If this is to be done, one thing that has to be thought of is:
>>
>> - We need one of the requested VC's to be in HS mode for this. Do we
>> enable HS for a VC in the dsi driver itself? Currently, its the job
>> of
>> the panel driver to enable HSmode for a VC. Is this a clean approach?
>
> I have to say I don't have any idea what would be the best approach...
>
> What comes to my mind is that the DSI driver could automatically send
> the null packet, when:
>
> a) ddr_clk_always_on is set
> b) a channel is changed to HS and enabled (I guess it needs to be
> enabled also, does it?)

This approach sounds fine. The only drawback is that we send a NULL 
packet each time we enable a high speed channel. So if a panel is using 
2 VCs, and it wants high speed for both channels(for some reason), we 
will be sending a NULL packet unnecessarily.

One observation was that the DDR clock has to be enabled only after the 
bridge chip is reset. Enabling HS, and sending a NULL packet before 
doing a hw reset of the bridge chip doesn't bring up the panel(that is a 
bit peculiar). So we can't do this within omapdss_dsi_display_enable().

Archit

>
> Well, we do seem to enable all VCs at init phase (which, thinking about
> it, sounds a bit odd), so in practice we would just need to handle the
> omapdss_dsi_vc_enable_hs() case.
>
>   Tomi
>
>


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

* Re: [PATCH 10/10] OMAP: DSS2: DSI Video mode support
  2011-09-05  5:52             ` Archit Taneja
@ 2011-09-05  6:52               ` Tomi Valkeinen
  2011-09-05  7:11                 ` Archit Taneja
  0 siblings, 1 reply; 19+ messages in thread
From: Tomi Valkeinen @ 2011-09-05  6:52 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-omap

On Mon, 2011-09-05 at 11:22 +0530, Archit Taneja wrote:
> On Friday 02 September 2011 01:25 PM, Valkeinen, Tomi wrote:
> > On Fri, 2011-09-02 at 11:43 +0530, Archit Taneja wrote:
> >>> Sending a null packet to start the DDR clk is rather OMAP specific
> >>> internal thing, so I don't want to require the panel driver to need
> >> to
> >>> know that it must send a null packet to start the clock. So if the
> >> ddr
> >>> clk is not started automatically, I think we should have a function
> >> to
> >>> do that (dsi_start_ddr_clk or whatever), which will then send the
> >> null
> >>> packet (and perhaps return an error if DDR_CLK_ALWAYS_ON is not set,
> >>> dunno...).
> >>
> >> Okay, If we can confirm that a panel asks for DDR_CLK_ALWAYS_ON
> >> mainly
> >> because it doesn't have its own fclk, then the dsi driver surely
> >> needs
> >> to start the DDR clock by sending a NULL packet.
> >>
> >> If this is to be done, one thing that has to be thought of is:
> >>
> >> - We need one of the requested VC's to be in HS mode for this. Do we
> >> enable HS for a VC in the dsi driver itself? Currently, its the job
> >> of
> >> the panel driver to enable HSmode for a VC. Is this a clean approach?
> >
> > I have to say I don't have any idea what would be the best approach...
> >
> > What comes to my mind is that the DSI driver could automatically send
> > the null packet, when:
> >
> > a) ddr_clk_always_on is set
> > b) a channel is changed to HS and enabled (I guess it needs to be
> > enabled also, does it?)
> 
> This approach sounds fine. The only drawback is that we send a NULL 
> packet each time we enable a high speed channel. So if a panel is using 
> 2 VCs, and it wants high speed for both channels(for some reason), we 
> will be sending a NULL packet unnecessarily.

True. I don't see that doing any harm, though, so I guess it's ok.

> One observation was that the DDR clock has to be enabled only after the 
> bridge chip is reset. Enabling HS, and sending a NULL packet before 
> doing a hw reset of the bridge chip doesn't bring up the panel(that is a 
> bit peculiar). So we can't do this within omapdss_dsi_display_enable().

Well that does sound strange. What happens there? Any errors? Commands
still going through?

Hmm, although... Well, I'm guessing, but if the HW reset for the chip
causes the chip to pull down the DSI lanes, or something similar, it
could cause errors in the OMAP side. But is that happening or something
else?

 Tomi



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

* Re: [PATCH 10/10] OMAP: DSS2: DSI Video mode support
  2011-09-05  6:52               ` Tomi Valkeinen
@ 2011-09-05  7:11                 ` Archit Taneja
  0 siblings, 0 replies; 19+ messages in thread
From: Archit Taneja @ 2011-09-05  7:11 UTC (permalink / raw)
  To: Valkeinen, Tomi; +Cc: linux-omap

On Monday 05 September 2011 12:22 PM, Valkeinen, Tomi wrote:
> On Mon, 2011-09-05 at 11:22 +0530, Archit Taneja wrote:
>> On Friday 02 September 2011 01:25 PM, Valkeinen, Tomi wrote:
>>> On Fri, 2011-09-02 at 11:43 +0530, Archit Taneja wrote:
>>>>> Sending a null packet to start the DDR clk is rather OMAP specific
>>>>> internal thing, so I don't want to require the panel driver to need
>>>> to
>>>>> know that it must send a null packet to start the clock. So if the
>>>> ddr
>>>>> clk is not started automatically, I think we should have a function
>>>> to
>>>>> do that (dsi_start_ddr_clk or whatever), which will then send the
>>>> null
>>>>> packet (and perhaps return an error if DDR_CLK_ALWAYS_ON is not set,
>>>>> dunno...).
>>>>
>>>> Okay, If we can confirm that a panel asks for DDR_CLK_ALWAYS_ON
>>>> mainly
>>>> because it doesn't have its own fclk, then the dsi driver surely
>>>> needs
>>>> to start the DDR clock by sending a NULL packet.
>>>>
>>>> If this is to be done, one thing that has to be thought of is:
>>>>
>>>> - We need one of the requested VC's to be in HS mode for this. Do we
>>>> enable HS for a VC in the dsi driver itself? Currently, its the job
>>>> of
>>>> the panel driver to enable HSmode for a VC. Is this a clean approach?
>>>
>>> I have to say I don't have any idea what would be the best approach...
>>>
>>> What comes to my mind is that the DSI driver could automatically send
>>> the null packet, when:
>>>
>>> a) ddr_clk_always_on is set
>>> b) a channel is changed to HS and enabled (I guess it needs to be
>>> enabled also, does it?)
>>
>> This approach sounds fine. The only drawback is that we send a NULL
>> packet each time we enable a high speed channel. So if a panel is using
>> 2 VCs, and it wants high speed for both channels(for some reason), we
>> will be sending a NULL packet unnecessarily.
>
> True. I don't see that doing any harm, though, so I guess it's ok.
>
>> One observation was that the DDR clock has to be enabled only after the
>> bridge chip is reset. Enabling HS, and sending a NULL packet before
>> doing a hw reset of the bridge chip doesn't bring up the panel(that is a
>> bit peculiar). So we can't do this within omapdss_dsi_display_enable().
>
> Well that does sound strange. What happens there? Any errors? Commands
> still going through?

The commands go through from OMAP side, but we don't get BTA Acks. I get 
the following errors:

[    4.527069] omapdss DSI error: DSI error, irqstatus 100180
[    4.532836] DSI IRQ: 0x100180: PLL_LOCK PLL_UNLOCK TA_TIMEOUT

I am not sure why "PLL_UNLOCK" occurs, but TA_TIMEOUT would make sense 
if the bridge chip isn't working properly.

Archit

>
> Hmm, although... Well, I'm guessing, but if the HW reset for the chip
> causes the chip to pull down the DSI lanes, or something similar, it
> could cause errors in the OMAP side. But is that happening or something
> else?
>
>   Tomi
>
>


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

end of thread, other threads:[~2011-09-05  7:12 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-30 10:51 [PATCH 00/10] OMAP: DSS2: DSI: Initial DSI video mode support Archit Taneja
2011-08-30 10:51 ` [PATCH 01/10] OMAP: DSS2: Use MIPI DSI transacition types and commands from include/video/mipi_display.h Archit Taneja
2011-08-30 10:51 ` [PATCH 02/10] OMAP: DSS2: DSI: Represent L4 and VP as sources of VC instead of modes Archit Taneja
2011-08-30 10:51 ` [PATCH 03/10] OMAP: DSS2: Create enum for DSI operation modes Archit Taneja
2011-08-30 10:51 ` [PATCH 04/10] OMAP: DSS2: DSI: Introduce generic write functions Archit Taneja
2011-08-30 10:51 ` [PATCH 05/10] OMAP: DSS2: DSI: Remove functions dsi_vc_dcs_read_1() and dsi_vc_dcs_read_2() Archit Taneja
2011-08-30 10:51 ` [PATCH 06/10] OMAP: DSS2: DSI: Split dsi_vc_dcs_read() into 2 functions Archit Taneja
2011-08-30 10:51 ` [PATCH 07/10] OMAP: DSS2: DSI: Introduce generic read functions Archit Taneja
2011-08-30 10:51 ` [PATCH 08/10] OMAP: DSS2: Clean up stallmode and io pad mode selection Archit Taneja
2011-08-30 10:51 ` [PATCH 09/10] OMAP: DSS2: Create an enum for DSI pixel formats Archit Taneja
2011-08-30 10:51 ` [PATCH 10/10] OMAP: DSS2: DSI Video mode support Archit Taneja
2011-09-01 13:14   ` Tomi Valkeinen
2011-09-02  5:15     ` Archit Taneja
2011-09-02  5:32       ` Tomi Valkeinen
2011-09-02  6:13         ` Archit Taneja
2011-09-02  7:55           ` Tomi Valkeinen
2011-09-05  5:52             ` Archit Taneja
2011-09-05  6:52               ` Tomi Valkeinen
2011-09-05  7:11                 ` Archit Taneja

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.