aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2011-05-16 05:47:08 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2011-05-16 06:31:09 -0400
commit75d7247c07d27d046323504e2dbca5b3e94fbece (patch)
tree69b545fb4181fbd9fd50dd2a36cb68eab731e443 /drivers/video/omap2
parent49dbf5892fc67466ac2780c1d42d8a02726f5538 (diff)
OMAP: DSS2: DSI: Get number of DSI data lanes using DSI_GNQ register
On OMAP3, the DSI module has 2 data lanes. On OMAP4, DSI1 has 4 data lanes and DSI2 has 2 data lanes. Introduce function dsi_get_num_data_lanes() which returns the number of data lanes on the dsi interface, introduce function dsi_get_num_data_lanes_dssdev() which returns the number of data lanes used by the omap_dss_device connected to the lanes. Use the DSI_GNQ register on OMAP4 to get the number of data lanes, modify dsi.c to use the number of lanes and the extra data lanes on DSI1. Signed-off-by: Archit Taneja <archit@ti.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2')
-rw-r--r--drivers/video/omap2/dss/dsi.c97
-rw-r--r--drivers/video/omap2/dss/dss_features.c3
-rw-r--r--drivers/video/omap2/dss/dss_features.h1
3 files changed, 91 insertions, 10 deletions
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index f04244bba76..784677d088f 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -59,6 +59,7 @@ struct dsi_reg { u16 idx; };
59#define DSI_IRQSTATUS DSI_REG(0x0018) 59#define DSI_IRQSTATUS DSI_REG(0x0018)
60#define DSI_IRQENABLE DSI_REG(0x001C) 60#define DSI_IRQENABLE DSI_REG(0x001C)
61#define DSI_CTRL DSI_REG(0x0040) 61#define DSI_CTRL DSI_REG(0x0040)
62#define DSI_GNQ DSI_REG(0x0044)
62#define DSI_COMPLEXIO_CFG1 DSI_REG(0x0048) 63#define DSI_COMPLEXIO_CFG1 DSI_REG(0x0048)
63#define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(0x004C) 64#define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(0x004C)
64#define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(0x0050) 65#define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(0x0050)
@@ -238,6 +239,10 @@ enum dsi_lane {
238 DSI_DATA1_N = 1 << 3, 239 DSI_DATA1_N = 1 << 3,
239 DSI_DATA2_P = 1 << 4, 240 DSI_DATA2_P = 1 << 4,
240 DSI_DATA2_N = 1 << 5, 241 DSI_DATA2_N = 1 << 5,
242 DSI_DATA3_P = 1 << 6,
243 DSI_DATA3_N = 1 << 7,
244 DSI_DATA4_P = 1 << 8,
245 DSI_DATA4_N = 1 << 9,
241}; 246};
242 247
243struct dsi_update_region { 248struct dsi_update_region {
@@ -326,6 +331,8 @@ struct dsi_data {
326 unsigned long fint_min, fint_max; 331 unsigned long fint_min, fint_max;
327 unsigned long lpdiv_max; 332 unsigned long lpdiv_max;
328 333
334 int num_data_lanes;
335
329 unsigned scp_clk_refcount; 336 unsigned scp_clk_refcount;
330}; 337};
331 338
@@ -2001,10 +2008,39 @@ static int dsi_cio_power(struct platform_device *dsidev,
2001 return 0; 2008 return 0;
2002} 2009}
2003 2010
2011/* Number of data lanes present on DSI interface */
2012static inline int dsi_get_num_data_lanes(struct platform_device *dsidev)
2013{
2014 /* DSI on OMAP3 doesn't have register DSI_GNQ, set number
2015 * of data lanes as 2 by default */
2016 if (dss_has_feature(FEAT_DSI_GNQ))
2017 return REG_GET(dsidev, DSI_GNQ, 11, 9); /* NB_DATA_LANES */
2018 else
2019 return 2;
2020}
2021
2022/* Number of data lanes used by the dss device */
2023static inline int dsi_get_num_data_lanes_dssdev(struct omap_dss_device *dssdev)
2024{
2025 int num_data_lanes = 0;
2026
2027 if (dssdev->phy.dsi.data1_lane != 0)
2028 num_data_lanes++;
2029 if (dssdev->phy.dsi.data2_lane != 0)
2030 num_data_lanes++;
2031 if (dssdev->phy.dsi.data3_lane != 0)
2032 num_data_lanes++;
2033 if (dssdev->phy.dsi.data4_lane != 0)
2034 num_data_lanes++;
2035
2036 return num_data_lanes;
2037}
2038
2004static void dsi_set_lane_config(struct omap_dss_device *dssdev) 2039static void dsi_set_lane_config(struct omap_dss_device *dssdev)
2005{ 2040{
2006 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 2041 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2007 u32 r; 2042 u32 r;
2043 int num_data_lanes_dssdev = dsi_get_num_data_lanes_dssdev(dssdev);
2008 2044
2009 int clk_lane = dssdev->phy.dsi.clk_lane; 2045 int clk_lane = dssdev->phy.dsi.clk_lane;
2010 int data1_lane = dssdev->phy.dsi.data1_lane; 2046 int data1_lane = dssdev->phy.dsi.data1_lane;
@@ -2020,6 +2056,20 @@ static void dsi_set_lane_config(struct omap_dss_device *dssdev)
2020 r = FLD_MOD(r, data1_pol, 7, 7); 2056 r = FLD_MOD(r, data1_pol, 7, 7);
2021 r = FLD_MOD(r, data2_lane, 10, 8); 2057 r = FLD_MOD(r, data2_lane, 10, 8);
2022 r = FLD_MOD(r, data2_pol, 11, 11); 2058 r = FLD_MOD(r, data2_pol, 11, 11);
2059 if (num_data_lanes_dssdev > 2) {
2060 int data3_lane = dssdev->phy.dsi.data3_lane;
2061 int data3_pol = dssdev->phy.dsi.data3_pol;
2062
2063 r = FLD_MOD(r, data3_lane, 14, 12);
2064 r = FLD_MOD(r, data3_pol, 15, 15);
2065 }
2066 if (num_data_lanes_dssdev > 3) {
2067 int data4_lane = dssdev->phy.dsi.data4_lane;
2068 int data4_pol = dssdev->phy.dsi.data4_pol;
2069
2070 r = FLD_MOD(r, data4_lane, 18, 16);
2071 r = FLD_MOD(r, data4_pol, 19, 19);
2072 }
2023 dsi_write_reg(dsidev, DSI_COMPLEXIO_CFG1, r); 2073 dsi_write_reg(dsidev, DSI_COMPLEXIO_CFG1, r);
2024 2074
2025 /* The configuration of the DSI complex I/O (number of data lanes, 2075 /* The configuration of the DSI complex I/O (number of data lanes,
@@ -2132,14 +2182,20 @@ static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev,
2132 enum dsi_lane lanes) 2182 enum dsi_lane lanes)
2133{ 2183{
2134 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 2184 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2185 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2135 int clk_lane = dssdev->phy.dsi.clk_lane; 2186 int clk_lane = dssdev->phy.dsi.clk_lane;
2136 int data1_lane = dssdev->phy.dsi.data1_lane; 2187 int data1_lane = dssdev->phy.dsi.data1_lane;
2137 int data2_lane = dssdev->phy.dsi.data2_lane; 2188 int data2_lane = dssdev->phy.dsi.data2_lane;
2189 int data3_lane = dssdev->phy.dsi.data3_lane;
2190 int data4_lane = dssdev->phy.dsi.data4_lane;
2138 int clk_pol = dssdev->phy.dsi.clk_pol; 2191 int clk_pol = dssdev->phy.dsi.clk_pol;
2139 int data1_pol = dssdev->phy.dsi.data1_pol; 2192 int data1_pol = dssdev->phy.dsi.data1_pol;
2140 int data2_pol = dssdev->phy.dsi.data2_pol; 2193 int data2_pol = dssdev->phy.dsi.data2_pol;
2194 int data3_pol = dssdev->phy.dsi.data3_pol;
2195 int data4_pol = dssdev->phy.dsi.data4_pol;
2141 2196
2142 u32 l = 0; 2197 u32 l = 0;
2198 u8 lptxscp_start = dsi->num_data_lanes == 2 ? 22 : 26;
2143 2199
2144 if (lanes & DSI_CLK_P) 2200 if (lanes & DSI_CLK_P)
2145 l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 0 : 1)); 2201 l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 0 : 1));
@@ -2156,17 +2212,28 @@ static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev,
2156 if (lanes & DSI_DATA2_N) 2212 if (lanes & DSI_DATA2_N)
2157 l |= 1 << ((data2_lane - 1) * 2 + (data2_pol ? 1 : 0)); 2213 l |= 1 << ((data2_lane - 1) * 2 + (data2_pol ? 1 : 0));
2158 2214
2215 if (lanes & DSI_DATA3_P)
2216 l |= 1 << ((data3_lane - 1) * 2 + (data3_pol ? 0 : 1));
2217 if (lanes & DSI_DATA3_N)
2218 l |= 1 << ((data3_lane - 1) * 2 + (data3_pol ? 1 : 0));
2219
2220 if (lanes & DSI_DATA4_P)
2221 l |= 1 << ((data4_lane - 1) * 2 + (data4_pol ? 0 : 1));
2222 if (lanes & DSI_DATA4_N)
2223 l |= 1 << ((data4_lane - 1) * 2 + (data4_pol ? 1 : 0));
2159 /* 2224 /*
2160 * Bits in REGLPTXSCPDAT4TO0DXDY: 2225 * Bits in REGLPTXSCPDAT4TO0DXDY:
2161 * 17: DY0 18: DX0 2226 * 17: DY0 18: DX0
2162 * 19: DY1 20: DX1 2227 * 19: DY1 20: DX1
2163 * 21: DY2 22: DX2 2228 * 21: DY2 22: DX2
2229 * 23: DY3 24: DX3
2230 * 25: DY4 26: DX4
2164 */ 2231 */
2165 2232
2166 /* Set the lane override configuration */ 2233 /* Set the lane override configuration */
2167 2234
2168 /* REGLPTXSCPDAT4TO0DXDY */ 2235 /* REGLPTXSCPDAT4TO0DXDY */
2169 REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, l, 22, 17); 2236 REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, l, lptxscp_start, 17);
2170 2237
2171 /* Enable lane override */ 2238 /* Enable lane override */
2172 2239
@@ -2248,6 +2315,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
2248 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 2315 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2249 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 2316 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2250 int r; 2317 int r;
2318 int num_data_lanes_dssdev = dsi_get_num_data_lanes_dssdev(dssdev);
2251 u32 l; 2319 u32 l;
2252 2320
2253 DSSDBGF(); 2321 DSSDBGF();
@@ -2279,6 +2347,8 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
2279 dsi_write_reg(dsidev, DSI_TIMING1, l); 2347 dsi_write_reg(dsidev, DSI_TIMING1, l);
2280 2348
2281 if (dsi->ulps_enabled) { 2349 if (dsi->ulps_enabled) {
2350 u32 lane_mask = DSI_CLK_P | DSI_DATA1_P | DSI_DATA2_P;
2351
2282 DSSDBG("manual ulps exit\n"); 2352 DSSDBG("manual ulps exit\n");
2283 2353
2284 /* ULPS is exited by Mark-1 state for 1ms, followed by 2354 /* ULPS is exited by Mark-1 state for 1ms, followed by
@@ -2289,8 +2359,13 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
2289 * manually. 2359 * manually.
2290 */ 2360 */
2291 2361
2292 dsi_cio_enable_lane_override(dssdev, 2362 if (num_data_lanes_dssdev > 2)
2293 DSI_CLK_P | DSI_DATA1_P | DSI_DATA2_P); 2363 lane_mask |= DSI_DATA3_P;
2364
2365 if (num_data_lanes_dssdev > 3)
2366 lane_mask |= DSI_DATA4_P;
2367
2368 dsi_cio_enable_lane_override(dssdev, lane_mask);
2294 } 2369 }
2295 2370
2296 r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON); 2371 r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON);
@@ -3495,12 +3570,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
3495 /* min 60ns + 52*UI */ 3570 /* min 60ns + 52*UI */
3496 tclk_post = ns2ddr(dsidev, 60) + 26; 3571 tclk_post = ns2ddr(dsidev, 60) + 26;
3497 3572
3498 /* ths_eot is 2 for 2 datalanes and 4 for 1 datalane */ 3573 ths_eot = DIV_ROUND_UP(4, dsi_get_num_data_lanes_dssdev(dssdev));
3499 if (dssdev->phy.dsi.data1_lane != 0 &&
3500 dssdev->phy.dsi.data2_lane != 0)
3501 ths_eot = 2;
3502 else
3503 ths_eot = 4;
3504 3574
3505 ddr_clk_pre = DIV_ROUND_UP(tclk_pre + tlpx + tclk_zero + tclk_prepare, 3575 ddr_clk_pre = DIV_ROUND_UP(tclk_pre + tlpx + tclk_zero + tclk_prepare,
3506 4); 3576 4);
@@ -4220,6 +4290,7 @@ int dsi_init_display(struct omap_dss_device *dssdev)
4220{ 4290{
4221 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4291 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4222 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4292 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4293 int dsi_module = dsi_get_dsidev_id(dsidev);
4223 4294
4224 DSSDBG("DSI init\n"); 4295 DSSDBG("DSI init\n");
4225 4296
@@ -4240,6 +4311,12 @@ int dsi_init_display(struct omap_dss_device *dssdev)
4240 dsi->vdds_dsi_reg = vdds_dsi; 4311 dsi->vdds_dsi_reg = vdds_dsi;
4241 } 4312 }
4242 4313
4314 if (dsi_get_num_data_lanes_dssdev(dssdev) > dsi->num_data_lanes) {
4315 DSSERR("DSI%d can't support more than %d data lanes\n",
4316 dsi_module + 1, dsi->num_data_lanes);
4317 return -EINVAL;
4318 }
4319
4243 return 0; 4320 return 0;
4244} 4321}
4245 4322
@@ -4416,6 +4493,8 @@ static int dsi_init(struct platform_device *dsidev)
4416 dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n", 4493 dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n",
4417 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 4494 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
4418 4495
4496 dsi->num_data_lanes = dsi_get_num_data_lanes(dsidev);
4497
4419 enable_clocks(0); 4498 enable_clocks(0);
4420 4499
4421 return 0; 4500 return 0;
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 5be5eb0f149..6460b0af335 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -294,7 +294,8 @@ static const struct omap_dss_features omap4_dss_features = {
294 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA | 294 FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
295 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 | 295 FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 |
296 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC | 296 FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC |
297 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH, 297 FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH |
298 FEAT_DSI_GNQ,
298 299
299 .num_mgrs = 3, 300 .num_mgrs = 3,
300 .num_ovls = 3, 301 .num_ovls = 3,
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 857162b56f6..ff2cf33b07a 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -47,6 +47,7 @@ enum dss_feat_id {
47 FEAT_DSI_DCS_CMD_CONFIG_VC = 1 << 15, 47 FEAT_DSI_DCS_CMD_CONFIG_VC = 1 << 15,
48 FEAT_DSI_VC_OCP_WIDTH = 1 << 16, 48 FEAT_DSI_VC_OCP_WIDTH = 1 << 16,
49 FEAT_DSI_REVERSE_TXCLKESC = 1 << 17, 49 FEAT_DSI_REVERSE_TXCLKESC = 1 << 17,
50 FEAT_DSI_GNQ = 1 << 18,
50}; 51};
51 52
52/* DSS register field id */ 53/* DSS register field id */