diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2010-10-07 13:59:22 +0300 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2011-05-11 14:20:16 +0300 |
commit | 03329ace1dc7dc9319f6f405381d898fc66fb2cb (patch) | |
tree | ca282fb0107a545f66601921c85618732faffdb2 /drivers | |
parent | 65c62bb953d216aaf0e22692e8e12e5c568a3b02 (diff) |
OMAP: DSS2: DSI: wait for TXCLKESC domain to come out of reset
Add dsi_cio_wait_tx_clk_esc_reset() function which waits for the
TXCLKESC domains to come out of reset.
Things have worked fine without this, but better be safe than sorry.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index f4219628444..8bc443bae6b 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1969,6 +1969,65 @@ static void dsi_cio_disable_lane_override(void) REG_FLD_MOD(DSI_DSIPHY_CFG10, 0, 22, 17); /* REGLPTXSCPDAT4TO0DXDY */ } +static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *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; + + 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; + + t = 100000; + while (true) { + u32 l; + int i; + int ok; + + l = dsi_read_reg(DSI_DSIPHY_CFG5); + + ok = 0; + for (i = 0; i < 3; ++i) { + if (!in_use[i] || (l & (1 << bits[i]))) + ok++; + } + + if (ok == 3) + break; + + if (--t == 0) { + for (i = 0; i < 3; ++i) { + if (!in_use[i] || (l & (1 << bits[i]))) + continue; + + DSSERR("CIO TXCLKESC%d domain not coming " \ + "out of reset\n", i); + } + return -EIO; + } + } + + return 0; +} + static int dsi_cio_init(struct omap_dss_device *dssdev) { int r; @@ -2028,6 +2087,10 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) dsi_if_enable(false); REG_FLD_MOD(DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */ + r = dsi_cio_wait_tx_clk_esc_reset(dssdev); + if (r) + goto err_tx_clk_esc_rst; + if (dsi.ulps_enabled) { /* Keep Mark-1 state for 1ms (as per DSI spec) */ ktime_t wait = ns_to_ktime(1000 * 1000); @@ -2050,6 +2113,8 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) return 0; +err_tx_clk_esc_rst: + REG_FLD_MOD(DSI_CLK_CTRL, 0, 20, 20); /* LP_CLK_ENABLE */ err_cio_pwr_dom: dsi_cio_power(DSI_COMPLEXIO_POWER_OFF); err_cio_pwr: |