* [PATCH 00/13] OMAPDSS: DSI fixes
@ 2011-11-24 13:29 Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 01/13] OMAPDSS: DSI: flush posted write when entering ULPS Tomi Valkeinen
` (12 more replies)
0 siblings, 13 replies; 17+ messages in thread
From: Tomi Valkeinen @ 2011-11-24 13:29 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
First a few patches to flush posted writes, and then DSI patches related to the
DSI lane handling. I'm not sure if the lane handling is still as clean as it
could be, but at least it feels cleaner than currently.
Tested entering ULPS on display disable on blaze tablet, and it seems to work.
However, I have no way to ensure that ULPS was actually entered, as I would
need a scope for that.
Tomi
Tomi Valkeinen (13):
OMAPDSS: DSI: flush posted write when entering ULPS
OMAPDSS: DSI: flush posted write in send_bta
OMAPDSS: DISPC: Flush posted writes when enabling outputs
OMAPDSS: DSI: count with number of lanes
OMAPDSS: DSI: Parse lane config
OMAPDSS: DSI: Use new lane config in dsi_set_lane_config
OMAPDSS: DSI: use lane config in dsi_get_lane_mask
OMAPDSS: DSI: use lane config in dsi_cio_wait_tx_clk_esc_reset
OMAPDSS: DSI: use lane config in dsi_cio_enable_lane_override
OMAPDSS: DSI: remove dsi_get_num_lanes_used
OMAPDSS: DSI: fix lane handling when entering ULPS
OMAPDSS: DSI: improve wait_for_bit_change
OMAPDSS: DSI: disable DDR_CLK_ALWAYS_ON when entering ULPS
drivers/video/omap2/dss/dispc.c | 10 +-
drivers/video/omap2/dss/dsi.c | 429 +++++++++++++++++++++------------------
2 files changed, 242 insertions(+), 197 deletions(-)
--
1.7.4.1
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 01/13] OMAPDSS: DSI: flush posted write when entering ULPS
2011-11-24 13:29 [PATCH 00/13] OMAPDSS: DSI fixes Tomi Valkeinen
@ 2011-11-24 13:29 ` Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 02/13] OMAPDSS: DSI: flush posted write in send_bta Tomi Valkeinen
` (11 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Tomi Valkeinen @ 2011-11-24 13:29 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Flush posted write between writing the ULPS enable bits and waiting for
the interrupt.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 5abf8e7..1331f92 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -3561,6 +3561,9 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (1 << 0) | (1 << 1) | (1 << 2),
7, 5);
+ /* flush posted write and wait for SCP interface to finish the write */
+ dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG2);
+
if (wait_for_completion_timeout(&completion,
msecs_to_jiffies(1000)) = 0) {
DSSERR("ULPS enable timeout\n");
@@ -3575,6 +3578,9 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (0 << 0) | (0 << 1) | (0 << 2),
7, 5);
+ /* flush posted write and wait for SCP interface to finish the write */
+ dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG2);
+
dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ULPS);
dsi_if_enable(dsidev, false);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 02/13] OMAPDSS: DSI: flush posted write in send_bta
2011-11-24 13:29 [PATCH 00/13] OMAPDSS: DSI fixes Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 01/13] OMAPDSS: DSI: flush posted write when entering ULPS Tomi Valkeinen
@ 2011-11-24 13:29 ` Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 03/13] OMAPDSS: DISPC: Flush posted writes when enabling outputs Tomi Valkeinen
` (10 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Tomi Valkeinen @ 2011-11-24 13:29 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Flush posted write after setting the bit to send the BTA to ensure the
BTA is sent right away, as the code in dsi_vc_send_bta_sync() waits for
an interrupt caused indirectly by sending the BTA.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 1331f92..4b1c074 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -2913,6 +2913,9 @@ static int dsi_vc_send_bta(struct platform_device *dsidev, int channel)
REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */
+ /* flush posted write */
+ dsi_read_reg(dsidev, DSI_VC_CTRL(channel));
+
return 0;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 03/13] OMAPDSS: DISPC: Flush posted writes when enabling outputs
2011-11-24 13:29 [PATCH 00/13] OMAPDSS: DSI fixes Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 01/13] OMAPDSS: DSI: flush posted write when entering ULPS Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 02/13] OMAPDSS: DSI: flush posted write in send_bta Tomi Valkeinen
@ 2011-11-24 13:29 ` Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 04/13] OMAPDSS: DSI: count with number of lanes Tomi Valkeinen
` (9 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Tomi Valkeinen @ 2011-11-24 13:29 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Flush posted write in _enable_lcd_out() and _enable_digit_out(). This
ensures the the lcd/digit bit is written before the code starts waiting
for interrupts about enabling/disabling the output.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dispc.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 5c81533..5bbd838 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1916,10 +1916,14 @@ static void dispc_disable_isr(void *data, u32 mask)
static void _enable_lcd_out(enum omap_channel channel, bool enable)
{
- if (channel = OMAP_DSS_CHANNEL_LCD2)
+ if (channel = OMAP_DSS_CHANNEL_LCD2) {
REG_FLD_MOD(DISPC_CONTROL2, enable ? 1 : 0, 0, 0);
- else
+ /* flush posted write */
+ dispc_read_reg(DISPC_CONTROL2);
+ } else {
REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
+ dispc_read_reg(DISPC_CONTROL);
+ }
}
static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
@@ -1967,6 +1971,8 @@ static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
static void _enable_digit_out(bool enable)
{
REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1);
+ /* flush posted write */
+ dispc_read_reg(DISPC_CONTROL);
}
static void dispc_mgr_enable_digit_out(bool enable)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 04/13] OMAPDSS: DSI: count with number of lanes
2011-11-24 13:29 [PATCH 00/13] OMAPDSS: DSI fixes Tomi Valkeinen
` (2 preceding siblings ...)
2011-11-24 13:29 ` [PATCH 03/13] OMAPDSS: DISPC: Flush posted writes when enabling outputs Tomi Valkeinen
@ 2011-11-24 13:29 ` Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 05/13] OMAPDSS: DSI: Parse lane config Tomi Valkeinen
` (8 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Tomi Valkeinen @ 2011-11-24 13:29 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
DSI driver currently counts used lanes and number of supported lanes by
using the number of data lanes (i.e. excluding clock lane). This patch
changes this to use the number of all lanes so that the following lane
config patches are cleaner.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 49 ++++++++++++++++++----------------------
1 files changed, 22 insertions(+), 27 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 4b1c074..6a110b2 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -327,7 +327,7 @@ struct dsi_data {
unsigned long fint_min, fint_max;
unsigned long lpdiv_max;
- int num_data_lanes;
+ unsigned num_lanes_supported;
unsigned scp_clk_refcount;
};
@@ -2029,19 +2029,8 @@ static int dsi_cio_power(struct platform_device *dsidev,
return 0;
}
-/* Number of data lanes present on DSI interface */
-static inline int dsi_get_num_data_lanes(struct platform_device *dsidev)
-{
- /* DSI on OMAP3 doesn't have register DSI_GNQ, set number
- * of data lanes as 2 by default */
- if (dss_has_feature(FEAT_DSI_GNQ))
- return REG_GET(dsidev, DSI_GNQ, 11, 9); /* NB_DATA_LANES */
- else
- return 2;
-}
-
-/* Number of data lanes used by the dss device */
-static inline int dsi_get_num_data_lanes_dssdev(struct omap_dss_device *dssdev)
+/* Number of lanes used by the dss device */
+static inline int dsi_get_num_lanes_used(struct omap_dss_device *dssdev)
{
int num_data_lanes = 0;
@@ -2054,7 +2043,7 @@ static inline int dsi_get_num_data_lanes_dssdev(struct omap_dss_device *dssdev)
if (dssdev->phy.dsi.data4_lane != 0)
num_data_lanes++;
- return num_data_lanes;
+ return num_data_lanes + 1;
}
static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
@@ -2092,7 +2081,7 @@ static void dsi_set_lane_config(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
u32 r;
- int num_data_lanes_dssdev = dsi_get_num_data_lanes_dssdev(dssdev);
+ int num_lanes_used = dsi_get_num_lanes_used(dssdev);
int clk_lane = dssdev->phy.dsi.clk_lane;
int data1_lane = dssdev->phy.dsi.data1_lane;
@@ -2108,14 +2097,14 @@ static void dsi_set_lane_config(struct omap_dss_device *dssdev)
r = FLD_MOD(r, data1_pol, 7, 7);
r = FLD_MOD(r, data2_lane, 10, 8);
r = FLD_MOD(r, data2_pol, 11, 11);
- if (num_data_lanes_dssdev > 2) {
+ if (num_lanes_used > 3) {
int data3_lane = dssdev->phy.dsi.data3_lane;
int data3_pol = dssdev->phy.dsi.data3_pol;
r = FLD_MOD(r, data3_lane, 14, 12);
r = FLD_MOD(r, data3_pol, 15, 15);
}
- if (num_data_lanes_dssdev > 3) {
+ if (num_lanes_used > 4) {
int data4_lane = dssdev->phy.dsi.data4_lane;
int data4_pol = dssdev->phy.dsi.data4_pol;
@@ -2247,7 +2236,7 @@ static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev,
int data4_pol = dssdev->phy.dsi.data4_pol;
u32 l = 0;
- u8 lptxscp_start = dsi->num_data_lanes = 2 ? 22 : 26;
+ u8 lptxscp_start = dsi->num_lanes_supported = 3 ? 22 : 26;
if (lanes & DSI_CLK_P)
l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 0 : 1));
@@ -2385,7 +2374,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int r;
- int num_data_lanes_dssdev = dsi_get_num_data_lanes_dssdev(dssdev);
+ int num_lanes_used = dsi_get_num_lanes_used(dssdev);
u32 l;
DSSDBGF();
@@ -2430,10 +2419,10 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
* manually.
*/
- if (num_data_lanes_dssdev > 2)
+ if (num_lanes_used > 3)
lane_mask |= DSI_DATA3_P;
- if (num_data_lanes_dssdev > 3)
+ if (num_lanes_used > 4)
lane_mask |= DSI_DATA4_P;
dsi_cio_enable_lane_override(dssdev, lane_mask);
@@ -3852,7 +3841,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);
+ int ndl = dsi_get_num_lanes_used(dssdev) - 1;
u32 r;
r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0);
@@ -4552,9 +4541,9 @@ int dsi_init_display(struct omap_dss_device *dssdev)
dsi->vdds_dsi_reg = vdds_dsi;
}
- if (dsi_get_num_data_lanes_dssdev(dssdev) > dsi->num_data_lanes) {
- DSSERR("DSI%d can't support more than %d data lanes\n",
- dsi_module + 1, dsi->num_data_lanes);
+ if (dsi_get_num_lanes_used(dssdev) > dsi->num_lanes_supported) {
+ DSSERR("DSI%d can't support more than %d lanes\n",
+ dsi_module + 1, dsi->num_lanes_supported);
return -EINVAL;
}
@@ -4780,7 +4769,13 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n",
FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
- dsi->num_data_lanes = dsi_get_num_data_lanes(dsidev);
+ /* DSI on OMAP3 doesn't have register DSI_GNQ, set number
+ * of data to 3 by default */
+ if (dss_has_feature(FEAT_DSI_GNQ))
+ /* NB_DATA_LANES */
+ dsi->num_lanes_supported = 1 + REG_GET(dsidev, DSI_GNQ, 11, 9);
+ else
+ dsi->num_lanes_supported = 3;
dsi_runtime_put(dsidev);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 05/13] OMAPDSS: DSI: Parse lane config
2011-11-24 13:29 [PATCH 00/13] OMAPDSS: DSI fixes Tomi Valkeinen
` (3 preceding siblings ...)
2011-11-24 13:29 ` [PATCH 04/13] OMAPDSS: DSI: count with number of lanes Tomi Valkeinen
@ 2011-11-24 13:29 ` Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 06/13] OMAPDSS: DSI: Use new lane config in dsi_set_lane_config Tomi Valkeinen
` (7 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Tomi Valkeinen @ 2011-11-24 13:29 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Parse the lane configuration from the device data into internal lane
config format. This will be used in the following patches to clean up
the lane handling.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 83 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 83 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 6a110b2..aea110c 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -203,6 +203,21 @@ struct dsi_reg { u16 idx; };
typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
#define DSI_MAX_NR_ISRS 2
+#define DSI_MAX_NR_LANES 5
+
+enum dsi_lane_function {
+ DSI_LANE_UNUSED = 0,
+ DSI_LANE_CLK,
+ DSI_LANE_DATA1,
+ DSI_LANE_DATA2,
+ DSI_LANE_DATA3,
+ DSI_LANE_DATA4,
+};
+
+struct dsi_lane_config {
+ enum dsi_lane_function function;
+ u8 polarity;
+};
struct dsi_isr_data {
omap_dsi_isr_t isr;
@@ -329,6 +344,9 @@ struct dsi_data {
unsigned num_lanes_supported;
+ struct dsi_lane_config lanes[DSI_MAX_NR_LANES];
+ unsigned num_lanes_used;
+
unsigned scp_clk_refcount;
};
@@ -2077,6 +2095,65 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
}
}
+static int dsi_parse_lane_config(struct omap_dss_device *dssdev)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ u8 lanes[DSI_MAX_NR_LANES];
+ u8 polarities[DSI_MAX_NR_LANES];
+ int num_lanes, i;
+
+ static const enum dsi_lane_function functions[] = {
+ DSI_LANE_CLK,
+ DSI_LANE_DATA1,
+ DSI_LANE_DATA2,
+ DSI_LANE_DATA3,
+ DSI_LANE_DATA4,
+ };
+
+ lanes[0] = dssdev->phy.dsi.clk_lane;
+ lanes[1] = dssdev->phy.dsi.data1_lane;
+ lanes[2] = dssdev->phy.dsi.data2_lane;
+ lanes[3] = dssdev->phy.dsi.data3_lane;
+ lanes[4] = dssdev->phy.dsi.data4_lane;
+ polarities[0] = dssdev->phy.dsi.clk_pol;
+ polarities[1] = dssdev->phy.dsi.data1_pol;
+ polarities[2] = dssdev->phy.dsi.data2_pol;
+ polarities[3] = dssdev->phy.dsi.data3_pol;
+ polarities[4] = dssdev->phy.dsi.data4_pol;
+
+ num_lanes = 0;
+
+ for (i = 0; i < dsi->num_lanes_supported; ++i)
+ dsi->lanes[i].function = DSI_LANE_UNUSED;
+
+ for (i = 0; i < dsi->num_lanes_supported; ++i) {
+ int num;
+
+ if (lanes[i] = DSI_LANE_UNUSED)
+ break;
+
+ num = lanes[i] - 1;
+
+ if (num >= dsi->num_lanes_supported)
+ return -EINVAL;
+
+ if (dsi->lanes[num].function != DSI_LANE_UNUSED)
+ return -EINVAL;
+
+ dsi->lanes[num].function = functions[i];
+ dsi->lanes[num].polarity = polarities[i];
+ num_lanes++;
+ }
+
+ if (num_lanes < 2 || num_lanes > dsi->num_lanes_supported)
+ return -EINVAL;
+
+ dsi->num_lanes_used = num_lanes;
+
+ return 0;
+}
+
static void dsi_set_lane_config(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -4328,6 +4405,12 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
int dsi_module = dsi_get_dsidev_id(dsidev);
int r;
+ r = dsi_parse_lane_config(dssdev);
+ if (r) {
+ DSSERR("illegal lane config");
+ goto err0;
+ }
+
r = dsi_pll_init(dsidev, true, true);
if (r)
goto err0;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 06/13] OMAPDSS: DSI: Use new lane config in dsi_set_lane_config
2011-11-24 13:29 [PATCH 00/13] OMAPDSS: DSI fixes Tomi Valkeinen
` (4 preceding siblings ...)
2011-11-24 13:29 ` [PATCH 05/13] OMAPDSS: DSI: Parse lane config Tomi Valkeinen
@ 2011-11-24 13:29 ` Tomi Valkeinen
2011-11-28 9:08 ` [PATCH 06/13] OMAPDSS: DSI: Use new lane config in Carlos Chinea
2011-11-24 13:29 ` [PATCH 07/13] OMAPDSS: DSI: use lane config in dsi_get_lane_mask Tomi Valkeinen
` (6 subsequent siblings)
12 siblings, 1 reply; 17+ messages in thread
From: Tomi Valkeinen @ 2011-11-24 13:29 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Use the new lane config in dsi_set_lane_config().
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 84 +++++++++++++++++++---------------------
1 files changed, 40 insertions(+), 44 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index aea110c..ba8d6b3 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -2154,59 +2154,53 @@ static int dsi_parse_lane_config(struct omap_dss_device *dssdev)
return 0;
}
-static void dsi_set_lane_config(struct omap_dss_device *dssdev)
+static int dsi_set_lane_config(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ static const u8 offsets[] = { 0, 4, 8, 12, 16 };
+ static const enum dsi_lane_function functions[] = {
+ DSI_LANE_CLK,
+ DSI_LANE_DATA1,
+ DSI_LANE_DATA2,
+ DSI_LANE_DATA3,
+ DSI_LANE_DATA4,
+ };
u32 r;
- int num_lanes_used = dsi_get_num_lanes_used(dssdev);
-
- int clk_lane = dssdev->phy.dsi.clk_lane;
- int data1_lane = dssdev->phy.dsi.data1_lane;
- int data2_lane = dssdev->phy.dsi.data2_lane;
- int clk_pol = dssdev->phy.dsi.clk_pol;
- int data1_pol = dssdev->phy.dsi.data1_pol;
- int data2_pol = dssdev->phy.dsi.data2_pol;
+ int i;
r = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1);
- r = FLD_MOD(r, clk_lane, 2, 0);
- r = FLD_MOD(r, clk_pol, 3, 3);
- r = FLD_MOD(r, data1_lane, 6, 4);
- r = FLD_MOD(r, data1_pol, 7, 7);
- r = FLD_MOD(r, data2_lane, 10, 8);
- r = FLD_MOD(r, data2_pol, 11, 11);
- if (num_lanes_used > 3) {
- int data3_lane = dssdev->phy.dsi.data3_lane;
- int data3_pol = dssdev->phy.dsi.data3_pol;
-
- r = FLD_MOD(r, data3_lane, 14, 12);
- r = FLD_MOD(r, data3_pol, 15, 15);
+
+ for (i = 0; i < dsi->num_lanes_used; ++i) {
+ unsigned offset = offsets[i];
+ unsigned polarity, lane_number;
+ unsigned t;
+
+ for (t = 0; t < dsi->num_lanes_supported; ++t)
+ if (dsi->lanes[t].function = functions[i])
+ break;
+
+ if (t = dsi->num_lanes_supported)
+ return -EINVAL;
+
+ lane_number = t;
+ polarity = dsi->lanes[t].polarity;
+
+ r = FLD_MOD(r, lane_number + 1, offset + 2, offset);
+ r = FLD_MOD(r, polarity, offset + 3, offset + 3);
}
- if (num_lanes_used > 4) {
- int data4_lane = dssdev->phy.dsi.data4_lane;
- int data4_pol = dssdev->phy.dsi.data4_pol;
- r = FLD_MOD(r, data4_lane, 18, 16);
- r = FLD_MOD(r, data4_pol, 19, 19);
+ /* clear the unused lanes */
+ for (; i < dsi->num_lanes_supported; ++i) {
+ unsigned offset = offsets[i];
+
+ r = FLD_MOD(r, 0, offset + 2, offset);
+ r = FLD_MOD(r, 0, offset + 3, offset + 3);
}
- dsi_write_reg(dsidev, DSI_COMPLEXIO_CFG1, r);
- /* The configuration of the DSI complex I/O (number of data lanes,
- position, differential order) should not be changed while
- DSS.DSI_CLK_CRTRL[20] LP_CLK_ENABLE bit is set to 1. In order for
- the hardware to take into account a new configuration of the complex
- I/O (done in DSS.DSI_COMPLEXIO_CFG1 register), it is recommended to
- follow this sequence: First set the DSS.DSI_CTRL[0] IF_EN bit to 1,
- then reset the DSS.DSI_CTRL[0] IF_EN to 0, then set
- DSS.DSI_CLK_CTRL[20] LP_CLK_ENABLE to 1 and finally set again the
- DSS.DSI_CTRL[0] IF_EN bit to 1. If the sequence is not followed, the
- DSI complex I/O configuration is unknown. */
+ dsi_write_reg(dsidev, DSI_COMPLEXIO_CFG1, r);
- /*
- REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0);
- REG_FLD_MOD(dsidev, DSI_CTRL, 0, 0, 0);
- REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20);
- REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0);
- */
+ return 0;
}
static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns)
@@ -2473,7 +2467,9 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
goto err_scp_clk_dom;
}
- dsi_set_lane_config(dssdev);
+ r = dsi_set_lane_config(dssdev);
+ if (r)
+ goto err_scp_clk_dom;
/* set TX STOP MODE timer to maximum for this operation */
l = dsi_read_reg(dsidev, DSI_TIMING1);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 07/13] OMAPDSS: DSI: use lane config in dsi_get_lane_mask
2011-11-24 13:29 [PATCH 00/13] OMAPDSS: DSI fixes Tomi Valkeinen
` (5 preceding siblings ...)
2011-11-24 13:29 ` [PATCH 06/13] OMAPDSS: DSI: Use new lane config in dsi_set_lane_config Tomi Valkeinen
@ 2011-11-24 13:29 ` Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 08/13] OMAPDSS: DSI: use lane config in dsi_cio_wait_tx_clk_esc_reset Tomi Valkeinen
` (5 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Tomi Valkeinen @ 2011-11-24 13:29 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Use the new lane config in dsi_get_lane_mask().
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 22 ++++++++++------------
1 files changed, 10 insertions(+), 12 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index ba8d6b3..1a209a2 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -2422,22 +2422,20 @@ static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
return 0;
}
+/* return bitmask of enabled lanes, lane0 being the lsb */
static unsigned dsi_get_lane_mask(struct omap_dss_device *dssdev)
{
- unsigned lanes = 0;
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ unsigned mask = 0;
+ int i;
- if (dssdev->phy.dsi.clk_lane != 0)
- lanes |= 1 << (dssdev->phy.dsi.clk_lane - 1);
- if (dssdev->phy.dsi.data1_lane != 0)
- lanes |= 1 << (dssdev->phy.dsi.data1_lane - 1);
- if (dssdev->phy.dsi.data2_lane != 0)
- lanes |= 1 << (dssdev->phy.dsi.data2_lane - 1);
- if (dssdev->phy.dsi.data3_lane != 0)
- lanes |= 1 << (dssdev->phy.dsi.data3_lane - 1);
- if (dssdev->phy.dsi.data4_lane != 0)
- lanes |= 1 << (dssdev->phy.dsi.data4_lane - 1);
+ for (i = 0; i < dsi->num_lanes_supported; ++i) {
+ if (dsi->lanes[i].function != DSI_LANE_UNUSED)
+ mask |= 1 << i;
+ }
- return lanes;
+ return mask;
}
static int dsi_cio_init(struct omap_dss_device *dssdev)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 08/13] OMAPDSS: DSI: use lane config in dsi_cio_wait_tx_clk_esc_reset
2011-11-24 13:29 [PATCH 00/13] OMAPDSS: DSI fixes Tomi Valkeinen
` (6 preceding siblings ...)
2011-11-24 13:29 ` [PATCH 07/13] OMAPDSS: DSI: use lane config in dsi_get_lane_mask Tomi Valkeinen
@ 2011-11-24 13:29 ` Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 09/13] OMAPDSS: DSI: use lane config in dsi_cio_enable_lane_override Tomi Valkeinen
` (4 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Tomi Valkeinen @ 2011-11-24 13:29 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Use the new lane config in dsi_cio_wait_tx_clk_esc_reset(). This also
extends the function to support 5 lanes on OMAP4, instead of 3 lanes.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 47 +++++++++++++++-------------------------
1 files changed, 18 insertions(+), 29 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 1a209a2..52cf97f 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -2365,51 +2365,40 @@ static void dsi_cio_disable_lane_override(struct platform_device *dsidev)
static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
- int t;
- int bits[3];
- bool in_use[3];
-
- if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) {
- bits[0] = 28;
- bits[1] = 27;
- bits[2] = 26;
- } else {
- bits[0] = 24;
- bits[1] = 25;
- bits[2] = 26;
- }
-
- in_use[0] = false;
- in_use[1] = false;
- in_use[2] = false;
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ int t, i;
+ bool in_use[DSI_MAX_NR_LANES];
+ static const u8 offsets_old[] = { 28, 27, 26 };
+ static const u8 offsets_new[] = { 24, 25, 26, 27, 28 };
+ const u8 *offsets;
+
+ if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC))
+ offsets = offsets_old;
+ else
+ offsets = offsets_new;
- if (dssdev->phy.dsi.clk_lane != 0)
- in_use[dssdev->phy.dsi.clk_lane - 1] = true;
- if (dssdev->phy.dsi.data1_lane != 0)
- in_use[dssdev->phy.dsi.data1_lane - 1] = true;
- if (dssdev->phy.dsi.data2_lane != 0)
- in_use[dssdev->phy.dsi.data2_lane - 1] = true;
+ for (i = 0; i < dsi->num_lanes_supported; ++i)
+ in_use[i] = dsi->lanes[i].function != DSI_LANE_UNUSED;
t = 100000;
while (true) {
u32 l;
- int i;
int ok;
l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
ok = 0;
- for (i = 0; i < 3; ++i) {
- if (!in_use[i] || (l & (1 << bits[i])))
+ for (i = 0; i < dsi->num_lanes_supported; ++i) {
+ if (!in_use[i] || (l & (1 << offsets[i])))
ok++;
}
- if (ok = 3)
+ if (ok = dsi->num_lanes_supported)
break;
if (--t = 0) {
- for (i = 0; i < 3; ++i) {
- if (!in_use[i] || (l & (1 << bits[i])))
+ for (i = 0; i < dsi->num_lanes_supported; ++i) {
+ if (!in_use[i] || (l & (1 << offsets[i])))
continue;
DSSERR("CIO TXCLKESC%d domain not coming " \
--
1.7.4.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 09/13] OMAPDSS: DSI: use lane config in dsi_cio_enable_lane_override
2011-11-24 13:29 [PATCH 00/13] OMAPDSS: DSI fixes Tomi Valkeinen
` (7 preceding siblings ...)
2011-11-24 13:29 ` [PATCH 08/13] OMAPDSS: DSI: use lane config in dsi_cio_wait_tx_clk_esc_reset Tomi Valkeinen
@ 2011-11-24 13:29 ` Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 10/13] OMAPDSS: DSI: remove dsi_get_num_lanes_used Tomi Valkeinen
` (3 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Tomi Valkeinen @ 2011-11-24 13:29 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
Use the new lane config in dsi_cio_enable_lane_override(). The function
parameters are also slightly changed.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 85 +++++++++++++----------------------------
1 files changed, 27 insertions(+), 58 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 52cf97f..dee9525 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -238,19 +238,6 @@ enum dsi_vc_source {
DSI_VC_SOURCE_VP,
};
-enum dsi_lane {
- DSI_CLK_P = 1 << 0,
- DSI_CLK_N = 1 << 1,
- DSI_DATA1_P = 1 << 2,
- DSI_DATA1_N = 1 << 3,
- DSI_DATA2_P = 1 << 4,
- DSI_DATA2_N = 1 << 5,
- DSI_DATA3_P = 1 << 6,
- DSI_DATA3_N = 1 << 7,
- DSI_DATA4_P = 1 << 8,
- DSI_DATA4_N = 1 << 9,
-};
-
struct dsi_update_region {
u16 x, y, w, h;
struct omap_dss_device *device;
@@ -2290,49 +2277,28 @@ static void dsi_cio_timings(struct platform_device *dsidev)
dsi_write_reg(dsidev, DSI_DSIPHY_CFG2, r);
}
+/* lane masks have lane 0 at lsb. mask_p for positive lines, n for negative */
static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev,
- enum dsi_lane lanes)
+ unsigned mask_p, unsigned mask_n)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- int clk_lane = dssdev->phy.dsi.clk_lane;
- int data1_lane = dssdev->phy.dsi.data1_lane;
- int data2_lane = dssdev->phy.dsi.data2_lane;
- int data3_lane = dssdev->phy.dsi.data3_lane;
- int data4_lane = dssdev->phy.dsi.data4_lane;
- int clk_pol = dssdev->phy.dsi.clk_pol;
- int data1_pol = dssdev->phy.dsi.data1_pol;
- int data2_pol = dssdev->phy.dsi.data2_pol;
- int data3_pol = dssdev->phy.dsi.data3_pol;
- int data4_pol = dssdev->phy.dsi.data4_pol;
-
- u32 l = 0;
+ int i;
+ u32 l;
u8 lptxscp_start = dsi->num_lanes_supported = 3 ? 22 : 26;
- if (lanes & DSI_CLK_P)
- l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 0 : 1));
- if (lanes & DSI_CLK_N)
- l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 1 : 0));
-
- if (lanes & DSI_DATA1_P)
- l |= 1 << ((data1_lane - 1) * 2 + (data1_pol ? 0 : 1));
- if (lanes & DSI_DATA1_N)
- l |= 1 << ((data1_lane - 1) * 2 + (data1_pol ? 1 : 0));
-
- if (lanes & DSI_DATA2_P)
- l |= 1 << ((data2_lane - 1) * 2 + (data2_pol ? 0 : 1));
- if (lanes & DSI_DATA2_N)
- l |= 1 << ((data2_lane - 1) * 2 + (data2_pol ? 1 : 0));
-
- if (lanes & DSI_DATA3_P)
- l |= 1 << ((data3_lane - 1) * 2 + (data3_pol ? 0 : 1));
- if (lanes & DSI_DATA3_N)
- l |= 1 << ((data3_lane - 1) * 2 + (data3_pol ? 1 : 0));
-
- if (lanes & DSI_DATA4_P)
- l |= 1 << ((data4_lane - 1) * 2 + (data4_pol ? 0 : 1));
- if (lanes & DSI_DATA4_N)
- l |= 1 << ((data4_lane - 1) * 2 + (data4_pol ? 1 : 0));
+ l = 0;
+
+ for (i = 0; i < dsi->num_lanes_supported; ++i) {
+ unsigned p = dsi->lanes[i].polarity;
+
+ if (mask_p & (1 << i))
+ l |= 1 << (i * 2 + (p ? 0 : 1));
+
+ if (mask_n & (1 << i))
+ l |= 1 << (i * 2 + (p ? 1 : 0));
+ }
+
/*
* Bits in REGLPTXSCPDAT4TO0DXDY:
* 17: DY0 18: DX0
@@ -2432,7 +2398,6 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int r;
- int num_lanes_used = dsi_get_num_lanes_used(dssdev);
u32 l;
DSSDBGF();
@@ -2467,7 +2432,8 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
dsi_write_reg(dsidev, DSI_TIMING1, l);
if (dsi->ulps_enabled) {
- u32 lane_mask = DSI_CLK_P | DSI_DATA1_P | DSI_DATA2_P;
+ unsigned mask_p;
+ int i;
DSSDBG("manual ulps exit\n");
@@ -2476,16 +2442,19 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
* ULPS exit sequence, as after reset the DSS HW thinks
* that we are not in ULPS mode, and refuses to send the
* sequence. So we need to send the ULPS exit sequence
- * manually.
+ * manually by setting positive lines high and negative lines
+ * low for 1ms.
*/
- if (num_lanes_used > 3)
- lane_mask |= DSI_DATA3_P;
+ mask_p = 0;
- if (num_lanes_used > 4)
- lane_mask |= DSI_DATA4_P;
+ for (i = 0; i < dsi->num_lanes_supported; ++i) {
+ if (dsi->lanes[i].function = DSI_LANE_UNUSED)
+ continue;
+ mask_p |= 1 << i;
+ }
- dsi_cio_enable_lane_override(dssdev, lane_mask);
+ dsi_cio_enable_lane_override(dssdev, mask_p, 0);
}
r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 10/13] OMAPDSS: DSI: remove dsi_get_num_lanes_used
2011-11-24 13:29 [PATCH 00/13] OMAPDSS: DSI fixes Tomi Valkeinen
` (8 preceding siblings ...)
2011-11-24 13:29 ` [PATCH 09/13] OMAPDSS: DSI: use lane config in dsi_cio_enable_lane_override Tomi Valkeinen
@ 2011-11-24 13:29 ` Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 11/13] OMAPDSS: DSI: fix lane handling when entering ULPS Tomi Valkeinen
` (2 subsequent siblings)
12 siblings, 0 replies; 17+ messages in thread
From: Tomi Valkeinen @ 2011-11-24 13:29 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
There's no longer need for the dsi_get_num_lanes_used function, so it
can be removed. The lane check in dsi_init_display() can be removed as
the validity of the config will be verified when parsing it.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 27 ++-------------------------
1 files changed, 2 insertions(+), 25 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index dee9525..2b375c6 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -2034,23 +2034,6 @@ static int dsi_cio_power(struct platform_device *dsidev,
return 0;
}
-/* Number of lanes used by the dss device */
-static inline int dsi_get_num_lanes_used(struct omap_dss_device *dssdev)
-{
- int num_data_lanes = 0;
-
- if (dssdev->phy.dsi.data1_lane != 0)
- num_data_lanes++;
- if (dssdev->phy.dsi.data2_lane != 0)
- num_data_lanes++;
- if (dssdev->phy.dsi.data3_lane != 0)
- num_data_lanes++;
- if (dssdev->phy.dsi.data4_lane != 0)
- num_data_lanes++;
-
- return num_data_lanes + 1;
-}
-
static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
{
int val;
@@ -3863,6 +3846,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
static void dsi_proto_timings(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail;
unsigned tclk_pre, tclk_post;
unsigned ths_prepare, ths_prepare_ths_zero, ths_zero;
@@ -3870,7 +3854,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_lanes_used(dssdev) - 1;
+ int ndl = dsi->num_lanes_used - 1;
u32 r;
r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0);
@@ -4554,7 +4538,6 @@ int dsi_init_display(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- int dsi_module = dsi_get_dsidev_id(dsidev);
DSSDBG("DSI init\n");
@@ -4576,12 +4559,6 @@ int dsi_init_display(struct omap_dss_device *dssdev)
dsi->vdds_dsi_reg = vdds_dsi;
}
- if (dsi_get_num_lanes_used(dssdev) > dsi->num_lanes_supported) {
- DSSERR("DSI%d can't support more than %d lanes\n",
- dsi_module + 1, dsi->num_lanes_supported);
- return -EINVAL;
- }
-
return 0;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 11/13] OMAPDSS: DSI: fix lane handling when entering ULPS
2011-11-24 13:29 [PATCH 00/13] OMAPDSS: DSI fixes Tomi Valkeinen
` (9 preceding siblings ...)
2011-11-24 13:29 ` [PATCH 10/13] OMAPDSS: DSI: remove dsi_get_num_lanes_used Tomi Valkeinen
@ 2011-11-24 13:29 ` Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 12/13] OMAPDSS: DSI: improve wait_for_bit_change Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 13/13] OMAPDSS: DSI: disable DDR_CLK_ALWAYS_ON when entering ULPS Tomi Valkeinen
12 siblings, 0 replies; 17+ messages in thread
From: Tomi Valkeinen @ 2011-11-24 13:29 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
The current code always enters ULPS for 3 lanes. This is not right, as
there could be only 2 lanes used, and on OMAP4 we have 5 lanes.
Fix the code to put all used lanes into ULPS.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 16 +++++++++++-----
1 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 2b375c6..22055db 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -3517,7 +3517,8 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
DECLARE_COMPLETION_ONSTACK(completion);
- int r;
+ int r, i;
+ unsigned mask;
DSSDBGF();
@@ -3560,10 +3561,16 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
if (r)
return r;
+ mask = 0;
+
+ for (i = 0; i < dsi->num_lanes_supported; ++i) {
+ if (dsi->lanes[i].function = DSI_LANE_UNUSED)
+ continue;
+ mask |= 1 << i;
+ }
/* Assert TxRequestEsc for data lanes and TxUlpsClk for clk lane */
/* LANEx_ULPS_SIG2 */
- REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (1 << 0) | (1 << 1) | (1 << 2),
- 7, 5);
+ REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, mask, 9, 5);
/* flush posted write and wait for SCP interface to finish the write */
dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG2);
@@ -3579,8 +3586,7 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
/* Reset LANEx_ULPS_SIG2 */
- REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (0 << 0) | (0 << 1) | (0 << 2),
- 7, 5);
+ REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, 0, 9, 5);
/* flush posted write and wait for SCP interface to finish the write */
dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG2);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 12/13] OMAPDSS: DSI: improve wait_for_bit_change
2011-11-24 13:29 [PATCH 00/13] OMAPDSS: DSI fixes Tomi Valkeinen
` (10 preceding siblings ...)
2011-11-24 13:29 ` [PATCH 11/13] OMAPDSS: DSI: fix lane handling when entering ULPS Tomi Valkeinen
@ 2011-11-24 13:29 ` Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 13/13] OMAPDSS: DSI: disable DDR_CLK_ALWAYS_ON when entering ULPS Tomi Valkeinen
12 siblings, 0 replies; 17+ messages in thread
From: Tomi Valkeinen @ 2011-11-24 13:29 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
We sometimes get timeout when disabling the DSI interface with video
mode. It looks like the disable will stall until the current frame has
been finished, and this can take multiple milliseconds.
wait_for_bit_change() currently uses a busyloop to wait for a bit to
change. This is used in multiple places. The problem is, we don't have
clear understanding how long particular operations can take, so the
function needs to support longer waits.
Improve wait_for_bit_change() to first busy loop for 100 times to see if
the bit changes almost right away. If the bit hasn't changed, move to a
loop with a sleep of 1ms, and poll for 500ms.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 25 ++++++++++++++++++++-----
1 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 22055db..a01a011 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -418,14 +418,29 @@ static void dsi_completion_handler(void *data, u32 mask)
static inline int wait_for_bit_change(struct platform_device *dsidev,
const struct dsi_reg idx, int bitnum, int value)
{
- int t = 100000;
+ unsigned long timeout;
+ ktime_t wait;
+ int t;
+
+ /* first busyloop to see if the bit changes right away */
+ t = 100;
+ while (t-- > 0) {
+ if (REG_GET(dsidev, idx, bitnum, bitnum) = value)
+ return value;
+ }
+
+ /* then loop for 500ms, sleeping for 1ms in between */
+ timeout = jiffies + msecs_to_jiffies(500);
+ while (time_before(jiffies, timeout)) {
+ if (REG_GET(dsidev, idx, bitnum, bitnum) = value)
+ return value;
- while (REG_GET(dsidev, idx, bitnum, bitnum) != value) {
- if (--t = 0)
- return !value;
+ wait = ns_to_ktime(1000 * 1000);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_hrtimeout(&wait, HRTIMER_MODE_REL);
}
- return value;
+ return !value;
}
u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 13/13] OMAPDSS: DSI: disable DDR_CLK_ALWAYS_ON when entering ULPS
2011-11-24 13:29 [PATCH 00/13] OMAPDSS: DSI fixes Tomi Valkeinen
` (11 preceding siblings ...)
2011-11-24 13:29 ` [PATCH 12/13] OMAPDSS: DSI: improve wait_for_bit_change Tomi Valkeinen
@ 2011-11-24 13:29 ` Tomi Valkeinen
12 siblings, 0 replies; 17+ messages in thread
From: Tomi Valkeinen @ 2011-11-24 13:29 UTC (permalink / raw)
To: linux-fbdev, linux-omap; +Cc: archit, Tomi Valkeinen
ULPS cannot be entered if the DDR clk is enabled. Thus disable the DDR
clk before entering ULPS.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dsi.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index a01a011..9bcb5c2 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -3544,9 +3544,11 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
if (dsi->ulps_enabled)
return 0;
+ /* DDR_CLK_ALWAYS_ON */
if (REG_GET(dsidev, DSI_CLK_CTRL, 13, 13)) {
- DSSERR("DDR_CLK_ALWAYS_ON enabled when entering ULPS\n");
- return -EIO;
+ dsi_if_enable(dsidev, 0);
+ REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 13, 13);
+ dsi_if_enable(dsidev, 1);
}
dsi_sync_vc(dsidev, 0);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 06/13] OMAPDSS: DSI: Use new lane config in
2011-11-24 13:29 ` [PATCH 06/13] OMAPDSS: DSI: Use new lane config in dsi_set_lane_config Tomi Valkeinen
@ 2011-11-28 9:08 ` Carlos Chinea
2011-11-28 15:43 ` Tomi Valkeinen
0 siblings, 1 reply; 17+ messages in thread
From: Carlos Chinea @ 2011-11-28 9:08 UTC (permalink / raw)
To: ext Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, archit
Hi Tomi,
Just a question/suggestion, bellow:
On Thu, 2011-11-24 at 15:29 +0200, ext Tomi Valkeinen wrote:
> Use the new lane config in dsi_set_lane_config().
>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> ---
> drivers/video/omap2/dss/dsi.c | 84 +++++++++++++++++++---------------------
> 1 files changed, 40 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
> index aea110c..ba8d6b3 100644
> --- a/drivers/video/omap2/dss/dsi.c
> +++ b/drivers/video/omap2/dss/dsi.c
> @@ -2154,59 +2154,53 @@ static int dsi_parse_lane_config(struct omap_dss_device *dssdev)
> return 0;
> }
>
> -static void dsi_set_lane_config(struct omap_dss_device *dssdev)
> +static int dsi_set_lane_config(struct omap_dss_device *dssdev)
> {
> struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
> + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
> + static const u8 offsets[] = { 0, 4, 8, 12, 16 };
> + static const enum dsi_lane_function functions[] = {
> + DSI_LANE_CLK,
> + DSI_LANE_DATA1,
> + DSI_LANE_DATA2,
> + DSI_LANE_DATA3,
> + DSI_LANE_DATA4,
> + };
Patch 05 of the series has a function (dsi_parse_lane_config) with
exactly the same static local declaration. Wouldn't be better to have an
static global declaration instead to save some space ? or are the values
from those functions going to differ in the near future ?
Br,
Carlos
> u32 r;
> - int num_lanes_used = dsi_get_num_lanes_used(dssdev);
> -
> - int clk_lane = dssdev->phy.dsi.clk_lane;
> - int data1_lane = dssdev->phy.dsi.data1_lane;
> - int data2_lane = dssdev->phy.dsi.data2_lane;
> - int clk_pol = dssdev->phy.dsi.clk_pol;
> - int data1_pol = dssdev->phy.dsi.data1_pol;
> - int data2_pol = dssdev->phy.dsi.data2_pol;
> + int i;
>
> r = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1);
> - r = FLD_MOD(r, clk_lane, 2, 0);
> - r = FLD_MOD(r, clk_pol, 3, 3);
> - r = FLD_MOD(r, data1_lane, 6, 4);
> - r = FLD_MOD(r, data1_pol, 7, 7);
> - r = FLD_MOD(r, data2_lane, 10, 8);
> - r = FLD_MOD(r, data2_pol, 11, 11);
> - if (num_lanes_used > 3) {
> - int data3_lane = dssdev->phy.dsi.data3_lane;
> - int data3_pol = dssdev->phy.dsi.data3_pol;
> -
> - r = FLD_MOD(r, data3_lane, 14, 12);
> - r = FLD_MOD(r, data3_pol, 15, 15);
> +
> + for (i = 0; i < dsi->num_lanes_used; ++i) {
> + unsigned offset = offsets[i];
> + unsigned polarity, lane_number;
> + unsigned t;
> +
> + for (t = 0; t < dsi->num_lanes_supported; ++t)
> + if (dsi->lanes[t].function = functions[i])
> + break;
> +
> + if (t = dsi->num_lanes_supported)
> + return -EINVAL;
> +
> + lane_number = t;
> + polarity = dsi->lanes[t].polarity;
> +
> + r = FLD_MOD(r, lane_number + 1, offset + 2, offset);
> + r = FLD_MOD(r, polarity, offset + 3, offset + 3);
> }
> - if (num_lanes_used > 4) {
> - int data4_lane = dssdev->phy.dsi.data4_lane;
> - int data4_pol = dssdev->phy.dsi.data4_pol;
>
> - r = FLD_MOD(r, data4_lane, 18, 16);
> - r = FLD_MOD(r, data4_pol, 19, 19);
> + /* clear the unused lanes */
> + for (; i < dsi->num_lanes_supported; ++i) {
> + unsigned offset = offsets[i];
> +
> + r = FLD_MOD(r, 0, offset + 2, offset);
> + r = FLD_MOD(r, 0, offset + 3, offset + 3);
> }
> - dsi_write_reg(dsidev, DSI_COMPLEXIO_CFG1, r);
>
> - /* The configuration of the DSI complex I/O (number of data lanes,
> - position, differential order) should not be changed while
> - DSS.DSI_CLK_CRTRL[20] LP_CLK_ENABLE bit is set to 1. In order for
> - the hardware to take into account a new configuration of the complex
> - I/O (done in DSS.DSI_COMPLEXIO_CFG1 register), it is recommended to
> - follow this sequence: First set the DSS.DSI_CTRL[0] IF_EN bit to 1,
> - then reset the DSS.DSI_CTRL[0] IF_EN to 0, then set
> - DSS.DSI_CLK_CTRL[20] LP_CLK_ENABLE to 1 and finally set again the
> - DSS.DSI_CTRL[0] IF_EN bit to 1. If the sequence is not followed, the
> - DSI complex I/O configuration is unknown. */
> + dsi_write_reg(dsidev, DSI_COMPLEXIO_CFG1, r);
>
> - /*
> - REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0);
> - REG_FLD_MOD(dsidev, DSI_CTRL, 0, 0, 0);
> - REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20);
> - REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0);
> - */
> + return 0;
> }
>
> static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns)
> @@ -2473,7 +2467,9 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
> goto err_scp_clk_dom;
> }
>
> - dsi_set_lane_config(dssdev);
> + r = dsi_set_lane_config(dssdev);
> + if (r)
> + goto err_scp_clk_dom;
>
> /* set TX STOP MODE timer to maximum for this operation */
> l = dsi_read_reg(dsidev, DSI_TIMING1);
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 06/13] OMAPDSS: DSI: Use new lane config in
2011-11-28 9:08 ` [PATCH 06/13] OMAPDSS: DSI: Use new lane config in Carlos Chinea
@ 2011-11-28 15:43 ` Tomi Valkeinen
2011-11-29 9:09 ` Carlos Chinea
0 siblings, 1 reply; 17+ messages in thread
From: Tomi Valkeinen @ 2011-11-28 15:43 UTC (permalink / raw)
To: Carlos Chinea; +Cc: linux-fbdev, linux-omap, archit
[-- Attachment #1: Type: text/plain, Size: 2106 bytes --]
On Mon, 2011-11-28 at 11:08 +0200, Carlos Chinea wrote:
> Hi Tomi,
>
> Just a question/suggestion, bellow:
>
> On Thu, 2011-11-24 at 15:29 +0200, ext Tomi Valkeinen wrote:
> > Use the new lane config in dsi_set_lane_config().
> >
> > Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> > ---
> > drivers/video/omap2/dss/dsi.c | 84 +++++++++++++++++++---------------------
> > 1 files changed, 40 insertions(+), 44 deletions(-)
> >
> > diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
> > index aea110c..ba8d6b3 100644
> > --- a/drivers/video/omap2/dss/dsi.c
> > +++ b/drivers/video/omap2/dss/dsi.c
> > @@ -2154,59 +2154,53 @@ static int dsi_parse_lane_config(struct omap_dss_device *dssdev)
> > return 0;
> > }
> >
> > -static void dsi_set_lane_config(struct omap_dss_device *dssdev)
> > +static int dsi_set_lane_config(struct omap_dss_device *dssdev)
> > {
> > struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
> > + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
> > + static const u8 offsets[] = { 0, 4, 8, 12, 16 };
> > + static const enum dsi_lane_function functions[] = {
> > + DSI_LANE_CLK,
> > + DSI_LANE_DATA1,
> > + DSI_LANE_DATA2,
> > + DSI_LANE_DATA3,
> > + DSI_LANE_DATA4,
> > + };
>
> Patch 05 of the series has a function (dsi_parse_lane_config) with
> exactly the same static local declaration. Wouldn't be better to have an
> static global declaration instead to save some space ? or are the values
> from those functions going to differ in the near future ?
True, the array could be a global, and no, I don't think they'll change
in the near future.
But the data is more like function internal stuff than global data. The
functions want to parse and set the lane configs in particular order,
and use the array for that.
While the order happens to be the same in both functions, I still felt
the array is internal to each function rather than global data. Looking
from outside the function, the order doesn't matter. It's just an
internal detail.
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 06/13] OMAPDSS: DSI: Use new lane config in
2011-11-28 15:43 ` Tomi Valkeinen
@ 2011-11-29 9:09 ` Carlos Chinea
0 siblings, 0 replies; 17+ messages in thread
From: Carlos Chinea @ 2011-11-29 9:09 UTC (permalink / raw)
To: ext Tomi Valkeinen; +Cc: linux-fbdev, linux-omap, archit
On Mon, 2011-11-28 at 17:43 +0200, ext Tomi Valkeinen wrote:
> On Mon, 2011-11-28 at 11:08 +0200, Carlos Chinea wrote:
> > Hi Tomi,
> >
> > Just a question/suggestion, bellow:
> >
> > On Thu, 2011-11-24 at 15:29 +0200, ext Tomi Valkeinen wrote:
> > > Use the new lane config in dsi_set_lane_config().
> > >
> > > Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> > > ---
> > > drivers/video/omap2/dss/dsi.c | 84 +++++++++++++++++++---------------------
> > > 1 files changed, 40 insertions(+), 44 deletions(-)
> > >
> > > diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
> > > index aea110c..ba8d6b3 100644
> > > --- a/drivers/video/omap2/dss/dsi.c
> > > +++ b/drivers/video/omap2/dss/dsi.c
> > > @@ -2154,59 +2154,53 @@ static int dsi_parse_lane_config(struct omap_dss_device *dssdev)
> > > return 0;
> > > }
> > >
> > > -static void dsi_set_lane_config(struct omap_dss_device *dssdev)
> > > +static int dsi_set_lane_config(struct omap_dss_device *dssdev)
> > > {
> > > struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
> > > + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
> > > + static const u8 offsets[] = { 0, 4, 8, 12, 16 };
> > > + static const enum dsi_lane_function functions[] = {
> > > + DSI_LANE_CLK,
> > > + DSI_LANE_DATA1,
> > > + DSI_LANE_DATA2,
> > > + DSI_LANE_DATA3,
> > > + DSI_LANE_DATA4,
> > > + };
> >
> > Patch 05 of the series has a function (dsi_parse_lane_config) with
> > exactly the same static local declaration. Wouldn't be better to have an
> > static global declaration instead to save some space ? or are the values
> > from those functions going to differ in the near future ?
>
> True, the array could be a global, and no, I don't think they'll change
> in the near future.
>
> But the data is more like function internal stuff than global data. The
> functions want to parse and set the lane configs in particular order,
> and use the array for that.
>
> While the order happens to be the same in both functions, I still felt
> the array is internal to each function rather than global data.
Fine for me then.
Br,
Carlos
> Looking
> from outside the function, the order doesn't matter. It's just an
> internal detail.
>
> Tomi
>
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2011-11-29 9:09 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-24 13:29 [PATCH 00/13] OMAPDSS: DSI fixes Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 01/13] OMAPDSS: DSI: flush posted write when entering ULPS Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 02/13] OMAPDSS: DSI: flush posted write in send_bta Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 03/13] OMAPDSS: DISPC: Flush posted writes when enabling outputs Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 04/13] OMAPDSS: DSI: count with number of lanes Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 05/13] OMAPDSS: DSI: Parse lane config Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 06/13] OMAPDSS: DSI: Use new lane config in dsi_set_lane_config Tomi Valkeinen
2011-11-28 9:08 ` [PATCH 06/13] OMAPDSS: DSI: Use new lane config in Carlos Chinea
2011-11-28 15:43 ` Tomi Valkeinen
2011-11-29 9:09 ` Carlos Chinea
2011-11-24 13:29 ` [PATCH 07/13] OMAPDSS: DSI: use lane config in dsi_get_lane_mask Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 08/13] OMAPDSS: DSI: use lane config in dsi_cio_wait_tx_clk_esc_reset Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 09/13] OMAPDSS: DSI: use lane config in dsi_cio_enable_lane_override Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 10/13] OMAPDSS: DSI: remove dsi_get_num_lanes_used Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 11/13] OMAPDSS: DSI: fix lane handling when entering ULPS Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 12/13] OMAPDSS: DSI: improve wait_for_bit_change Tomi Valkeinen
2011-11-24 13:29 ` [PATCH 13/13] OMAPDSS: DSI: disable DDR_CLK_ALWAYS_ON when entering ULPS Tomi Valkeinen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).