diff options
Diffstat (limited to 'drivers/video/omap2/dss/dsi.c')
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 675 |
1 files changed, 519 insertions, 156 deletions
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 05ee04667af1..d64ac3842884 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c | |||
@@ -41,7 +41,6 @@ | |||
41 | 41 | ||
42 | #include <video/omapdss.h> | 42 | #include <video/omapdss.h> |
43 | #include <video/mipi_display.h> | 43 | #include <video/mipi_display.h> |
44 | #include <plat/clock.h> | ||
45 | 44 | ||
46 | #include "dss.h" | 45 | #include "dss.h" |
47 | #include "dss_features.h" | 46 | #include "dss_features.h" |
@@ -333,6 +332,12 @@ struct dsi_data { | |||
333 | unsigned scp_clk_refcount; | 332 | unsigned scp_clk_refcount; |
334 | 333 | ||
335 | struct dss_lcd_mgr_config mgr_config; | 334 | struct dss_lcd_mgr_config mgr_config; |
335 | struct omap_video_timings timings; | ||
336 | enum omap_dss_dsi_pixel_format pix_fmt; | ||
337 | enum omap_dss_dsi_mode mode; | ||
338 | struct omap_dss_dsi_videomode_timings vm_timings; | ||
339 | |||
340 | struct omap_dss_output output; | ||
336 | }; | 341 | }; |
337 | 342 | ||
338 | struct dsi_packet_sent_handler_data { | 343 | struct dsi_packet_sent_handler_data { |
@@ -340,8 +345,6 @@ struct dsi_packet_sent_handler_data { | |||
340 | struct completion *completion; | 345 | struct completion *completion; |
341 | }; | 346 | }; |
342 | 347 | ||
343 | static struct platform_device *dsi_pdev_map[MAX_NUM_DSI]; | ||
344 | |||
345 | #ifdef DEBUG | 348 | #ifdef DEBUG |
346 | static bool dsi_perf; | 349 | static bool dsi_perf; |
347 | module_param(dsi_perf, bool, 0644); | 350 | module_param(dsi_perf, bool, 0644); |
@@ -354,12 +357,19 @@ static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dside | |||
354 | 357 | ||
355 | static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev) | 358 | static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev) |
356 | { | 359 | { |
357 | return dsi_pdev_map[dssdev->phy.dsi.module]; | 360 | return dssdev->output->pdev; |
358 | } | 361 | } |
359 | 362 | ||
360 | struct platform_device *dsi_get_dsidev_from_id(int module) | 363 | struct platform_device *dsi_get_dsidev_from_id(int module) |
361 | { | 364 | { |
362 | return dsi_pdev_map[module]; | 365 | struct omap_dss_output *out; |
366 | enum omap_dss_output_id id; | ||
367 | |||
368 | id = module == 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; | ||
369 | |||
370 | out = omap_dss_get_output(id); | ||
371 | |||
372 | return out->pdev; | ||
363 | } | 373 | } |
364 | 374 | ||
365 | static inline void dsi_write_reg(struct platform_device *dsidev, | 375 | static inline void dsi_write_reg(struct platform_device *dsidev, |
@@ -1450,6 +1460,148 @@ found: | |||
1450 | return 0; | 1460 | return 0; |
1451 | } | 1461 | } |
1452 | 1462 | ||
1463 | static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev, | ||
1464 | unsigned long req_clkin4ddr, struct dsi_clock_info *cinfo) | ||
1465 | { | ||
1466 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1467 | struct dsi_clock_info cur, best; | ||
1468 | |||
1469 | DSSDBG("dsi_pll_calc_ddrfreq\n"); | ||
1470 | |||
1471 | memset(&best, 0, sizeof(best)); | ||
1472 | memset(&cur, 0, sizeof(cur)); | ||
1473 | |||
1474 | cur.clkin = clk_get_rate(dsi->sys_clk); | ||
1475 | |||
1476 | for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) { | ||
1477 | cur.fint = cur.clkin / cur.regn; | ||
1478 | |||
1479 | if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min) | ||
1480 | continue; | ||
1481 | |||
1482 | /* DSIPHY(MHz) = (2 * regm / regn) * clkin */ | ||
1483 | for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) { | ||
1484 | unsigned long a, b; | ||
1485 | |||
1486 | a = 2 * cur.regm * (cur.clkin/1000); | ||
1487 | b = cur.regn; | ||
1488 | cur.clkin4ddr = a / b * 1000; | ||
1489 | |||
1490 | if (cur.clkin4ddr > 1800 * 1000 * 1000) | ||
1491 | break; | ||
1492 | |||
1493 | if (abs(cur.clkin4ddr - req_clkin4ddr) < | ||
1494 | abs(best.clkin4ddr - req_clkin4ddr)) { | ||
1495 | best = cur; | ||
1496 | DSSDBG("best %ld\n", best.clkin4ddr); | ||
1497 | } | ||
1498 | |||
1499 | if (cur.clkin4ddr == req_clkin4ddr) | ||
1500 | goto found; | ||
1501 | } | ||
1502 | } | ||
1503 | found: | ||
1504 | if (cinfo) | ||
1505 | *cinfo = best; | ||
1506 | |||
1507 | return 0; | ||
1508 | } | ||
1509 | |||
1510 | static void dsi_pll_calc_dsi_fck(struct platform_device *dsidev, | ||
1511 | struct dsi_clock_info *cinfo) | ||
1512 | { | ||
1513 | unsigned long max_dsi_fck; | ||
1514 | |||
1515 | max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK); | ||
1516 | |||
1517 | cinfo->regm_dsi = DIV_ROUND_UP(cinfo->clkin4ddr, max_dsi_fck); | ||
1518 | cinfo->dsi_pll_hsdiv_dsi_clk = cinfo->clkin4ddr / cinfo->regm_dsi; | ||
1519 | } | ||
1520 | |||
1521 | static int dsi_pll_calc_dispc_fck(struct platform_device *dsidev, | ||
1522 | unsigned long req_pck, struct dsi_clock_info *cinfo, | ||
1523 | struct dispc_clock_info *dispc_cinfo) | ||
1524 | { | ||
1525 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1526 | unsigned regm_dispc, best_regm_dispc; | ||
1527 | unsigned long dispc_clk, best_dispc_clk; | ||
1528 | int min_fck_per_pck; | ||
1529 | unsigned long max_dss_fck; | ||
1530 | struct dispc_clock_info best_dispc; | ||
1531 | bool match; | ||
1532 | |||
1533 | max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); | ||
1534 | |||
1535 | min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; | ||
1536 | |||
1537 | if (min_fck_per_pck && | ||
1538 | req_pck * min_fck_per_pck > max_dss_fck) { | ||
1539 | DSSERR("Requested pixel clock not possible with the current " | ||
1540 | "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " | ||
1541 | "the constraint off.\n"); | ||
1542 | min_fck_per_pck = 0; | ||
1543 | } | ||
1544 | |||
1545 | retry: | ||
1546 | best_regm_dispc = 0; | ||
1547 | best_dispc_clk = 0; | ||
1548 | memset(&best_dispc, 0, sizeof(best_dispc)); | ||
1549 | match = false; | ||
1550 | |||
1551 | for (regm_dispc = 1; regm_dispc < dsi->regm_dispc_max; ++regm_dispc) { | ||
1552 | struct dispc_clock_info cur_dispc; | ||
1553 | |||
1554 | dispc_clk = cinfo->clkin4ddr / regm_dispc; | ||
1555 | |||
1556 | /* this will narrow down the search a bit, | ||
1557 | * but still give pixclocks below what was | ||
1558 | * requested */ | ||
1559 | if (dispc_clk < req_pck) | ||
1560 | break; | ||
1561 | |||
1562 | if (dispc_clk > max_dss_fck) | ||
1563 | continue; | ||
1564 | |||
1565 | if (min_fck_per_pck && dispc_clk < req_pck * min_fck_per_pck) | ||
1566 | continue; | ||
1567 | |||
1568 | match = true; | ||
1569 | |||
1570 | dispc_find_clk_divs(req_pck, dispc_clk, &cur_dispc); | ||
1571 | |||
1572 | if (abs(cur_dispc.pck - req_pck) < | ||
1573 | abs(best_dispc.pck - req_pck)) { | ||
1574 | best_regm_dispc = regm_dispc; | ||
1575 | best_dispc_clk = dispc_clk; | ||
1576 | best_dispc = cur_dispc; | ||
1577 | |||
1578 | if (cur_dispc.pck == req_pck) | ||
1579 | goto found; | ||
1580 | } | ||
1581 | } | ||
1582 | |||
1583 | if (!match) { | ||
1584 | if (min_fck_per_pck) { | ||
1585 | DSSERR("Could not find suitable clock settings.\n" | ||
1586 | "Turning FCK/PCK constraint off and" | ||
1587 | "trying again.\n"); | ||
1588 | min_fck_per_pck = 0; | ||
1589 | goto retry; | ||
1590 | } | ||
1591 | |||
1592 | DSSERR("Could not find suitable clock settings.\n"); | ||
1593 | |||
1594 | return -EINVAL; | ||
1595 | } | ||
1596 | found: | ||
1597 | cinfo->regm_dispc = best_regm_dispc; | ||
1598 | cinfo->dsi_pll_hsdiv_dispc_clk = best_dispc_clk; | ||
1599 | |||
1600 | *dispc_cinfo = best_dispc; | ||
1601 | |||
1602 | return 0; | ||
1603 | } | ||
1604 | |||
1453 | int dsi_pll_set_clock_div(struct platform_device *dsidev, | 1605 | int dsi_pll_set_clock_div(struct platform_device *dsidev, |
1454 | struct dsi_clock_info *cinfo) | 1606 | struct dsi_clock_info *cinfo) |
1455 | { | 1607 | { |
@@ -1526,21 +1678,27 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev, | |||
1526 | 1678 | ||
1527 | BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max); | 1679 | BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max); |
1528 | 1680 | ||
1681 | l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2); | ||
1682 | |||
1529 | if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) { | 1683 | if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) { |
1530 | f = cinfo->fint < 1000000 ? 0x3 : | 1684 | f = cinfo->fint < 1000000 ? 0x3 : |
1531 | cinfo->fint < 1250000 ? 0x4 : | 1685 | cinfo->fint < 1250000 ? 0x4 : |
1532 | cinfo->fint < 1500000 ? 0x5 : | 1686 | cinfo->fint < 1500000 ? 0x5 : |
1533 | cinfo->fint < 1750000 ? 0x6 : | 1687 | cinfo->fint < 1750000 ? 0x6 : |
1534 | 0x7; | 1688 | 0x7; |
1535 | } | ||
1536 | 1689 | ||
1537 | l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2); | ||
1538 | |||
1539 | if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) | ||
1540 | l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ | 1690 | l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ |
1691 | } else if (dss_has_feature(FEAT_DSI_PLL_SELFREQDCO)) { | ||
1692 | f = cinfo->clkin4ddr < 1000000000 ? 0x2 : 0x4; | ||
1693 | |||
1694 | l = FLD_MOD(l, f, 4, 1); /* PLL_SELFREQDCO */ | ||
1695 | } | ||
1696 | |||
1541 | l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ | 1697 | l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ |
1542 | l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ | 1698 | l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ |
1543 | l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ | 1699 | l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ |
1700 | if (dss_has_feature(FEAT_DSI_PLL_REFSEL)) | ||
1701 | l = FLD_MOD(l, 3, 22, 21); /* REF_SYSCLK = sysclk */ | ||
1544 | dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l); | 1702 | dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l); |
1545 | 1703 | ||
1546 | REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */ | 1704 | REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */ |
@@ -2004,15 +2162,16 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev) | |||
2004 | return 1194 * 3; /* 1194x24 bits */ | 2162 | return 1194 * 3; /* 1194x24 bits */ |
2005 | case 6: | 2163 | case 6: |
2006 | return 1365 * 3; /* 1365x24 bits */ | 2164 | return 1365 * 3; /* 1365x24 bits */ |
2165 | case 7: | ||
2166 | return 1920 * 3; /* 1920x24 bits */ | ||
2007 | default: | 2167 | default: |
2008 | BUG(); | 2168 | BUG(); |
2009 | return 0; | 2169 | return 0; |
2010 | } | 2170 | } |
2011 | } | 2171 | } |
2012 | 2172 | ||
2013 | static int dsi_set_lane_config(struct omap_dss_device *dssdev) | 2173 | static int dsi_set_lane_config(struct platform_device *dsidev) |
2014 | { | 2174 | { |
2015 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2016 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 2175 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
2017 | static const u8 offsets[] = { 0, 4, 8, 12, 16 }; | 2176 | static const u8 offsets[] = { 0, 4, 8, 12, 16 }; |
2018 | static const enum dsi_lane_function functions[] = { | 2177 | static const enum dsi_lane_function functions[] = { |
@@ -2136,9 +2295,16 @@ static void dsi_cio_timings(struct platform_device *dsidev) | |||
2136 | dsi_write_reg(dsidev, DSI_DSIPHY_CFG0, r); | 2295 | dsi_write_reg(dsidev, DSI_DSIPHY_CFG0, r); |
2137 | 2296 | ||
2138 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1); | 2297 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1); |
2139 | r = FLD_MOD(r, tlpx_half, 22, 16); | 2298 | r = FLD_MOD(r, tlpx_half, 20, 16); |
2140 | r = FLD_MOD(r, tclk_trail, 15, 8); | 2299 | r = FLD_MOD(r, tclk_trail, 15, 8); |
2141 | r = FLD_MOD(r, tclk_zero, 7, 0); | 2300 | r = FLD_MOD(r, tclk_zero, 7, 0); |
2301 | |||
2302 | if (dss_has_feature(FEAT_DSI_PHY_DCC)) { | ||
2303 | r = FLD_MOD(r, 0, 21, 21); /* DCCEN = disable */ | ||
2304 | r = FLD_MOD(r, 1, 22, 22); /* CLKINP_DIVBY2EN = enable */ | ||
2305 | r = FLD_MOD(r, 1, 23, 23); /* CLKINP_SEL = enable */ | ||
2306 | } | ||
2307 | |||
2142 | dsi_write_reg(dsidev, DSI_DSIPHY_CFG1, r); | 2308 | dsi_write_reg(dsidev, DSI_DSIPHY_CFG1, r); |
2143 | 2309 | ||
2144 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2); | 2310 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2); |
@@ -2147,10 +2313,9 @@ static void dsi_cio_timings(struct platform_device *dsidev) | |||
2147 | } | 2313 | } |
2148 | 2314 | ||
2149 | /* lane masks have lane 0 at lsb. mask_p for positive lines, n for negative */ | 2315 | /* lane masks have lane 0 at lsb. mask_p for positive lines, n for negative */ |
2150 | static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev, | 2316 | static void dsi_cio_enable_lane_override(struct platform_device *dsidev, |
2151 | unsigned mask_p, unsigned mask_n) | 2317 | unsigned mask_p, unsigned mask_n) |
2152 | { | 2318 | { |
2153 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2154 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 2319 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
2155 | int i; | 2320 | int i; |
2156 | u32 l; | 2321 | u32 l; |
@@ -2197,9 +2362,8 @@ static void dsi_cio_disable_lane_override(struct platform_device *dsidev) | |||
2197 | REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 0, 22, 17); | 2362 | REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 0, 22, 17); |
2198 | } | 2363 | } |
2199 | 2364 | ||
2200 | static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev) | 2365 | static int dsi_cio_wait_tx_clk_esc_reset(struct platform_device *dsidev) |
2201 | { | 2366 | { |
2202 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2203 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 2367 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
2204 | int t, i; | 2368 | int t, i; |
2205 | bool in_use[DSI_MAX_NR_LANES]; | 2369 | bool in_use[DSI_MAX_NR_LANES]; |
@@ -2247,9 +2411,8 @@ static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev) | |||
2247 | } | 2411 | } |
2248 | 2412 | ||
2249 | /* return bitmask of enabled lanes, lane0 being the lsb */ | 2413 | /* return bitmask of enabled lanes, lane0 being the lsb */ |
2250 | static unsigned dsi_get_lane_mask(struct omap_dss_device *dssdev) | 2414 | static unsigned dsi_get_lane_mask(struct platform_device *dsidev) |
2251 | { | 2415 | { |
2252 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2253 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 2416 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
2254 | unsigned mask = 0; | 2417 | unsigned mask = 0; |
2255 | int i; | 2418 | int i; |
@@ -2262,16 +2425,15 @@ static unsigned dsi_get_lane_mask(struct omap_dss_device *dssdev) | |||
2262 | return mask; | 2425 | return mask; |
2263 | } | 2426 | } |
2264 | 2427 | ||
2265 | static int dsi_cio_init(struct omap_dss_device *dssdev) | 2428 | static int dsi_cio_init(struct platform_device *dsidev) |
2266 | { | 2429 | { |
2267 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2268 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 2430 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
2269 | int r; | 2431 | int r; |
2270 | u32 l; | 2432 | u32 l; |
2271 | 2433 | ||
2272 | DSSDBGF(); | 2434 | DSSDBGF(); |
2273 | 2435 | ||
2274 | r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dssdev)); | 2436 | r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dsidev)); |
2275 | if (r) | 2437 | if (r) |
2276 | return r; | 2438 | return r; |
2277 | 2439 | ||
@@ -2288,7 +2450,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) | |||
2288 | goto err_scp_clk_dom; | 2450 | goto err_scp_clk_dom; |
2289 | } | 2451 | } |
2290 | 2452 | ||
2291 | r = dsi_set_lane_config(dssdev); | 2453 | r = dsi_set_lane_config(dsidev); |
2292 | if (r) | 2454 | if (r) |
2293 | goto err_scp_clk_dom; | 2455 | goto err_scp_clk_dom; |
2294 | 2456 | ||
@@ -2323,7 +2485,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) | |||
2323 | mask_p |= 1 << i; | 2485 | mask_p |= 1 << i; |
2324 | } | 2486 | } |
2325 | 2487 | ||
2326 | dsi_cio_enable_lane_override(dssdev, mask_p, 0); | 2488 | dsi_cio_enable_lane_override(dsidev, mask_p, 0); |
2327 | } | 2489 | } |
2328 | 2490 | ||
2329 | r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON); | 2491 | r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON); |
@@ -2340,7 +2502,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) | |||
2340 | dsi_if_enable(dsidev, false); | 2502 | dsi_if_enable(dsidev, false); |
2341 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */ | 2503 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */ |
2342 | 2504 | ||
2343 | r = dsi_cio_wait_tx_clk_esc_reset(dssdev); | 2505 | r = dsi_cio_wait_tx_clk_esc_reset(dsidev); |
2344 | if (r) | 2506 | if (r) |
2345 | goto err_tx_clk_esc_rst; | 2507 | goto err_tx_clk_esc_rst; |
2346 | 2508 | ||
@@ -2360,10 +2522,10 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) | |||
2360 | 2522 | ||
2361 | dsi_cio_timings(dsidev); | 2523 | dsi_cio_timings(dsidev); |
2362 | 2524 | ||
2363 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { | 2525 | if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { |
2364 | /* DDR_CLK_ALWAYS_ON */ | 2526 | /* DDR_CLK_ALWAYS_ON */ |
2365 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, | 2527 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, |
2366 | dssdev->panel.dsi_vm_data.ddr_clk_always_on, 13, 13); | 2528 | dsi->vm_timings.ddr_clk_always_on, 13, 13); |
2367 | } | 2529 | } |
2368 | 2530 | ||
2369 | dsi->ulps_enabled = false; | 2531 | dsi->ulps_enabled = false; |
@@ -2381,13 +2543,12 @@ err_cio_pwr: | |||
2381 | dsi_cio_disable_lane_override(dsidev); | 2543 | dsi_cio_disable_lane_override(dsidev); |
2382 | err_scp_clk_dom: | 2544 | err_scp_clk_dom: |
2383 | dsi_disable_scp_clk(dsidev); | 2545 | dsi_disable_scp_clk(dsidev); |
2384 | dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dssdev)); | 2546 | dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dsidev)); |
2385 | return r; | 2547 | return r; |
2386 | } | 2548 | } |
2387 | 2549 | ||
2388 | static void dsi_cio_uninit(struct omap_dss_device *dssdev) | 2550 | static void dsi_cio_uninit(struct platform_device *dsidev) |
2389 | { | 2551 | { |
2390 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2391 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 2552 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
2392 | 2553 | ||
2393 | /* DDR_CLK_ALWAYS_ON */ | 2554 | /* DDR_CLK_ALWAYS_ON */ |
@@ -2395,7 +2556,7 @@ static void dsi_cio_uninit(struct omap_dss_device *dssdev) | |||
2395 | 2556 | ||
2396 | dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF); | 2557 | dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF); |
2397 | dsi_disable_scp_clk(dsidev); | 2558 | dsi_disable_scp_clk(dsidev); |
2398 | dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dssdev)); | 2559 | dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dsidev)); |
2399 | } | 2560 | } |
2400 | 2561 | ||
2401 | static void dsi_config_tx_fifo(struct platform_device *dsidev, | 2562 | static void dsi_config_tx_fifo(struct platform_device *dsidev, |
@@ -2685,6 +2846,7 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, | |||
2685 | bool enable) | 2846 | bool enable) |
2686 | { | 2847 | { |
2687 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 2848 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
2849 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
2688 | 2850 | ||
2689 | DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable); | 2851 | DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable); |
2690 | 2852 | ||
@@ -2701,7 +2863,7 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, | |||
2701 | dsi_force_tx_stop_mode_io(dsidev); | 2863 | dsi_force_tx_stop_mode_io(dsidev); |
2702 | 2864 | ||
2703 | /* start the DDR clock by sending a NULL packet */ | 2865 | /* start the DDR clock by sending a NULL packet */ |
2704 | if (dssdev->panel.dsi_vm_data.ddr_clk_always_on && enable) | 2866 | if (dsi->vm_timings.ddr_clk_always_on && enable) |
2705 | dsi_vc_send_null(dssdev, channel); | 2867 | dsi_vc_send_null(dssdev, channel); |
2706 | } | 2868 | } |
2707 | EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs); | 2869 | EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs); |
@@ -2987,10 +3149,9 @@ int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel) | |||
2987 | } | 3149 | } |
2988 | EXPORT_SYMBOL(dsi_vc_send_null); | 3150 | EXPORT_SYMBOL(dsi_vc_send_null); |
2989 | 3151 | ||
2990 | static int dsi_vc_write_nosync_common(struct omap_dss_device *dssdev, | 3152 | static int dsi_vc_write_nosync_common(struct platform_device *dsidev, |
2991 | int channel, u8 *data, int len, enum dss_dsi_content_type type) | 3153 | int channel, u8 *data, int len, enum dss_dsi_content_type type) |
2992 | { | 3154 | { |
2993 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2994 | int r; | 3155 | int r; |
2995 | 3156 | ||
2996 | if (len == 0) { | 3157 | if (len == 0) { |
@@ -3021,7 +3182,9 @@ static int dsi_vc_write_nosync_common(struct omap_dss_device *dssdev, | |||
3021 | int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel, | 3182 | int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel, |
3022 | u8 *data, int len) | 3183 | u8 *data, int len) |
3023 | { | 3184 | { |
3024 | return dsi_vc_write_nosync_common(dssdev, channel, data, len, | 3185 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
3186 | |||
3187 | return dsi_vc_write_nosync_common(dsidev, channel, data, len, | ||
3025 | DSS_DSI_CONTENT_DCS); | 3188 | DSS_DSI_CONTENT_DCS); |
3026 | } | 3189 | } |
3027 | EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); | 3190 | EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); |
@@ -3029,7 +3192,9 @@ EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); | |||
3029 | int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel, | 3192 | int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel, |
3030 | u8 *data, int len) | 3193 | u8 *data, int len) |
3031 | { | 3194 | { |
3032 | return dsi_vc_write_nosync_common(dssdev, channel, data, len, | 3195 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
3196 | |||
3197 | return dsi_vc_write_nosync_common(dsidev, channel, data, len, | ||
3033 | DSS_DSI_CONTENT_GENERIC); | 3198 | DSS_DSI_CONTENT_GENERIC); |
3034 | } | 3199 | } |
3035 | EXPORT_SYMBOL(dsi_vc_generic_write_nosync); | 3200 | EXPORT_SYMBOL(dsi_vc_generic_write_nosync); |
@@ -3040,7 +3205,7 @@ static int dsi_vc_write_common(struct omap_dss_device *dssdev, int channel, | |||
3040 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3205 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
3041 | int r; | 3206 | int r; |
3042 | 3207 | ||
3043 | r = dsi_vc_write_nosync_common(dssdev, channel, data, len, type); | 3208 | r = dsi_vc_write_nosync_common(dsidev, channel, data, len, type); |
3044 | if (r) | 3209 | if (r) |
3045 | goto err; | 3210 | goto err; |
3046 | 3211 | ||
@@ -3118,10 +3283,9 @@ int dsi_vc_generic_write_2(struct omap_dss_device *dssdev, int channel, | |||
3118 | } | 3283 | } |
3119 | EXPORT_SYMBOL(dsi_vc_generic_write_2); | 3284 | EXPORT_SYMBOL(dsi_vc_generic_write_2); |
3120 | 3285 | ||
3121 | static int dsi_vc_dcs_send_read_request(struct omap_dss_device *dssdev, | 3286 | static int dsi_vc_dcs_send_read_request(struct platform_device *dsidev, |
3122 | int channel, u8 dcs_cmd) | 3287 | int channel, u8 dcs_cmd) |
3123 | { | 3288 | { |
3124 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
3125 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 3289 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
3126 | int r; | 3290 | int r; |
3127 | 3291 | ||
@@ -3139,10 +3303,9 @@ static int dsi_vc_dcs_send_read_request(struct omap_dss_device *dssdev, | |||
3139 | return 0; | 3303 | return 0; |
3140 | } | 3304 | } |
3141 | 3305 | ||
3142 | static int dsi_vc_generic_send_read_request(struct omap_dss_device *dssdev, | 3306 | static int dsi_vc_generic_send_read_request(struct platform_device *dsidev, |
3143 | int channel, u8 *reqdata, int reqlen) | 3307 | int channel, u8 *reqdata, int reqlen) |
3144 | { | 3308 | { |
3145 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
3146 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 3309 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
3147 | u16 data; | 3310 | u16 data; |
3148 | u8 data_type; | 3311 | u8 data_type; |
@@ -3291,7 +3454,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, | |||
3291 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3454 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
3292 | int r; | 3455 | int r; |
3293 | 3456 | ||
3294 | r = dsi_vc_dcs_send_read_request(dssdev, channel, dcs_cmd); | 3457 | r = dsi_vc_dcs_send_read_request(dsidev, channel, dcs_cmd); |
3295 | if (r) | 3458 | if (r) |
3296 | goto err; | 3459 | goto err; |
3297 | 3460 | ||
@@ -3322,7 +3485,7 @@ static int dsi_vc_generic_read(struct omap_dss_device *dssdev, int channel, | |||
3322 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3485 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
3323 | int r; | 3486 | int r; |
3324 | 3487 | ||
3325 | r = dsi_vc_generic_send_read_request(dssdev, channel, reqdata, reqlen); | 3488 | r = dsi_vc_generic_send_read_request(dsidev, channel, reqdata, reqlen); |
3326 | if (r) | 3489 | if (r) |
3327 | return r; | 3490 | return r; |
3328 | 3491 | ||
@@ -3604,15 +3767,15 @@ static void dsi_set_hs_tx_timeout(struct platform_device *dsidev, | |||
3604 | (total_ticks * 1000) / (fck / 1000 / 1000)); | 3767 | (total_ticks * 1000) / (fck / 1000 / 1000)); |
3605 | } | 3768 | } |
3606 | 3769 | ||
3607 | static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev) | 3770 | static void dsi_config_vp_num_line_buffers(struct platform_device *dsidev) |
3608 | { | 3771 | { |
3609 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3772 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
3610 | int num_line_buffers; | 3773 | int num_line_buffers; |
3611 | 3774 | ||
3612 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { | 3775 | if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { |
3613 | int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); | 3776 | int bpp = dsi_get_pixel_size(dsi->pix_fmt); |
3614 | unsigned line_buf_size = dsi_get_line_buf_size(dsidev); | 3777 | unsigned line_buf_size = dsi_get_line_buf_size(dsidev); |
3615 | struct omap_video_timings *timings = &dssdev->panel.timings; | 3778 | struct omap_video_timings *timings = &dsi->timings; |
3616 | /* | 3779 | /* |
3617 | * Don't use line buffers if width is greater than the video | 3780 | * Don't use line buffers if width is greater than the video |
3618 | * port's line buffer size | 3781 | * port's line buffer size |
@@ -3630,11 +3793,11 @@ static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev) | |||
3630 | REG_FLD_MOD(dsidev, DSI_CTRL, num_line_buffers, 13, 12); | 3793 | REG_FLD_MOD(dsidev, DSI_CTRL, num_line_buffers, 13, 12); |
3631 | } | 3794 | } |
3632 | 3795 | ||
3633 | static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev) | 3796 | static void dsi_config_vp_sync_events(struct platform_device *dsidev) |
3634 | { | 3797 | { |
3635 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3798 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
3636 | bool vsync_end = dssdev->panel.dsi_vm_data.vp_vsync_end; | 3799 | bool vsync_end = dsi->vm_timings.vp_vsync_end; |
3637 | bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end; | 3800 | bool hsync_end = dsi->vm_timings.vp_hsync_end; |
3638 | u32 r; | 3801 | u32 r; |
3639 | 3802 | ||
3640 | r = dsi_read_reg(dsidev, DSI_CTRL); | 3803 | r = dsi_read_reg(dsidev, DSI_CTRL); |
@@ -3648,13 +3811,13 @@ static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev) | |||
3648 | dsi_write_reg(dsidev, DSI_CTRL, r); | 3811 | dsi_write_reg(dsidev, DSI_CTRL, r); |
3649 | } | 3812 | } |
3650 | 3813 | ||
3651 | static void dsi_config_blanking_modes(struct omap_dss_device *dssdev) | 3814 | static void dsi_config_blanking_modes(struct platform_device *dsidev) |
3652 | { | 3815 | { |
3653 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3816 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
3654 | int blanking_mode = dssdev->panel.dsi_vm_data.blanking_mode; | 3817 | int blanking_mode = dsi->vm_timings.blanking_mode; |
3655 | int hfp_blanking_mode = dssdev->panel.dsi_vm_data.hfp_blanking_mode; | 3818 | int hfp_blanking_mode = dsi->vm_timings.hfp_blanking_mode; |
3656 | int hbp_blanking_mode = dssdev->panel.dsi_vm_data.hbp_blanking_mode; | 3819 | int hbp_blanking_mode = dsi->vm_timings.hbp_blanking_mode; |
3657 | int hsa_blanking_mode = dssdev->panel.dsi_vm_data.hsa_blanking_mode; | 3820 | int hsa_blanking_mode = dsi->vm_timings.hsa_blanking_mode; |
3658 | u32 r; | 3821 | u32 r; |
3659 | 3822 | ||
3660 | /* | 3823 | /* |
@@ -3741,8 +3904,8 @@ static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev) | |||
3741 | int ddr_clk_pre, ddr_clk_post, enter_hs_mode_lat, exit_hs_mode_lat; | 3904 | int ddr_clk_pre, ddr_clk_post, enter_hs_mode_lat, exit_hs_mode_lat; |
3742 | int tclk_trail, ths_exit, exiths_clk; | 3905 | int tclk_trail, ths_exit, exiths_clk; |
3743 | bool ddr_alwon; | 3906 | bool ddr_alwon; |
3744 | struct omap_video_timings *timings = &dssdev->panel.timings; | 3907 | struct omap_video_timings *timings = &dsi->timings; |
3745 | int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); | 3908 | int bpp = dsi_get_pixel_size(dsi->pix_fmt); |
3746 | int ndl = dsi->num_lanes_used - 1; | 3909 | int ndl = dsi->num_lanes_used - 1; |
3747 | int dsi_fclk_hsdiv = dssdev->clocks.dsi.regm_dsi + 1; | 3910 | int dsi_fclk_hsdiv = dssdev->clocks.dsi.regm_dsi + 1; |
3748 | int hsa_interleave_hs = 0, hsa_interleave_lp = 0; | 3911 | int hsa_interleave_hs = 0, hsa_interleave_lp = 0; |
@@ -3852,6 +4015,7 @@ static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev) | |||
3852 | static int dsi_proto_config(struct omap_dss_device *dssdev) | 4015 | static int dsi_proto_config(struct omap_dss_device *dssdev) |
3853 | { | 4016 | { |
3854 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4017 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4018 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
3855 | u32 r; | 4019 | u32 r; |
3856 | int buswidth = 0; | 4020 | int buswidth = 0; |
3857 | 4021 | ||
@@ -3871,7 +4035,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev) | |||
3871 | dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true); | 4035 | dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true); |
3872 | dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true); | 4036 | dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true); |
3873 | 4037 | ||
3874 | switch (dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt)) { | 4038 | switch (dsi_get_pixel_size(dsi->pix_fmt)) { |
3875 | case 16: | 4039 | case 16: |
3876 | buswidth = 0; | 4040 | buswidth = 0; |
3877 | break; | 4041 | break; |
@@ -3903,11 +4067,11 @@ static int dsi_proto_config(struct omap_dss_device *dssdev) | |||
3903 | 4067 | ||
3904 | dsi_write_reg(dsidev, DSI_CTRL, r); | 4068 | dsi_write_reg(dsidev, DSI_CTRL, r); |
3905 | 4069 | ||
3906 | dsi_config_vp_num_line_buffers(dssdev); | 4070 | dsi_config_vp_num_line_buffers(dsidev); |
3907 | 4071 | ||
3908 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { | 4072 | if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { |
3909 | dsi_config_vp_sync_events(dssdev); | 4073 | dsi_config_vp_sync_events(dsidev); |
3910 | dsi_config_blanking_modes(dssdev); | 4074 | dsi_config_blanking_modes(dsidev); |
3911 | dsi_config_cmd_mode_interleaving(dssdev); | 4075 | dsi_config_cmd_mode_interleaving(dssdev); |
3912 | } | 4076 | } |
3913 | 4077 | ||
@@ -3919,9 +4083,8 @@ static int dsi_proto_config(struct omap_dss_device *dssdev) | |||
3919 | return 0; | 4083 | return 0; |
3920 | } | 4084 | } |
3921 | 4085 | ||
3922 | static void dsi_proto_timings(struct omap_dss_device *dssdev) | 4086 | static void dsi_proto_timings(struct platform_device *dsidev) |
3923 | { | 4087 | { |
3924 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
3925 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4088 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
3926 | unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail; | 4089 | unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail; |
3927 | unsigned tclk_pre, tclk_post; | 4090 | unsigned tclk_pre, tclk_post; |
@@ -3941,7 +4104,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev) | |||
3941 | ths_exit = FLD_GET(r, 7, 0); | 4104 | ths_exit = FLD_GET(r, 7, 0); |
3942 | 4105 | ||
3943 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1); | 4106 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1); |
3944 | tlpx = FLD_GET(r, 22, 16) * 2; | 4107 | tlpx = FLD_GET(r, 20, 16) * 2; |
3945 | tclk_trail = FLD_GET(r, 15, 8); | 4108 | tclk_trail = FLD_GET(r, 15, 8); |
3946 | tclk_zero = FLD_GET(r, 7, 0); | 4109 | tclk_zero = FLD_GET(r, 7, 0); |
3947 | 4110 | ||
@@ -3984,18 +4147,18 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev) | |||
3984 | DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n", | 4147 | DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n", |
3985 | enter_hs_mode_lat, exit_hs_mode_lat); | 4148 | enter_hs_mode_lat, exit_hs_mode_lat); |
3986 | 4149 | ||
3987 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { | 4150 | if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { |
3988 | /* TODO: Implement a video mode check_timings function */ | 4151 | /* TODO: Implement a video mode check_timings function */ |
3989 | int hsa = dssdev->panel.dsi_vm_data.hsa; | 4152 | int hsa = dsi->vm_timings.hsa; |
3990 | int hfp = dssdev->panel.dsi_vm_data.hfp; | 4153 | int hfp = dsi->vm_timings.hfp; |
3991 | int hbp = dssdev->panel.dsi_vm_data.hbp; | 4154 | int hbp = dsi->vm_timings.hbp; |
3992 | int vsa = dssdev->panel.dsi_vm_data.vsa; | 4155 | int vsa = dsi->vm_timings.vsa; |
3993 | int vfp = dssdev->panel.dsi_vm_data.vfp; | 4156 | int vfp = dsi->vm_timings.vfp; |
3994 | int vbp = dssdev->panel.dsi_vm_data.vbp; | 4157 | int vbp = dsi->vm_timings.vbp; |
3995 | int window_sync = dssdev->panel.dsi_vm_data.window_sync; | 4158 | int window_sync = dsi->vm_timings.window_sync; |
3996 | bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end; | 4159 | bool hsync_end = dsi->vm_timings.vp_hsync_end; |
3997 | struct omap_video_timings *timings = &dssdev->panel.timings; | 4160 | struct omap_video_timings *timings = &dsi->timings; |
3998 | int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); | 4161 | int bpp = dsi_get_pixel_size(dsi->pix_fmt); |
3999 | int tl, t_he, width_bytes; | 4162 | int tl, t_he, width_bytes; |
4000 | 4163 | ||
4001 | t_he = hsync_end ? | 4164 | t_he = hsync_end ? |
@@ -4100,16 +4263,84 @@ int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev, | |||
4100 | } | 4263 | } |
4101 | EXPORT_SYMBOL(omapdss_dsi_configure_pins); | 4264 | EXPORT_SYMBOL(omapdss_dsi_configure_pins); |
4102 | 4265 | ||
4103 | int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) | 4266 | int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev, |
4267 | unsigned long ddr_clk, unsigned long lp_clk) | ||
4104 | { | 4268 | { |
4105 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4269 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4270 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4271 | struct dsi_clock_info cinfo; | ||
4272 | struct dispc_clock_info dispc_cinfo; | ||
4273 | unsigned lp_clk_div; | ||
4274 | unsigned long dsi_fclk; | ||
4106 | int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); | 4275 | int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); |
4276 | unsigned long pck; | ||
4277 | int r; | ||
4278 | |||
4279 | DSSDBGF("ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk); | ||
4280 | |||
4281 | mutex_lock(&dsi->lock); | ||
4282 | |||
4283 | /* Calculate PLL output clock */ | ||
4284 | r = dsi_pll_calc_ddrfreq(dsidev, ddr_clk * 4, &cinfo); | ||
4285 | if (r) | ||
4286 | goto err; | ||
4287 | |||
4288 | /* Calculate PLL's DSI clock */ | ||
4289 | dsi_pll_calc_dsi_fck(dsidev, &cinfo); | ||
4290 | |||
4291 | /* Calculate PLL's DISPC clock and pck & lck divs */ | ||
4292 | pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp; | ||
4293 | DSSDBG("finding dispc dividers for pck %lu\n", pck); | ||
4294 | r = dsi_pll_calc_dispc_fck(dsidev, pck, &cinfo, &dispc_cinfo); | ||
4295 | if (r) | ||
4296 | goto err; | ||
4297 | |||
4298 | /* Calculate LP clock */ | ||
4299 | dsi_fclk = cinfo.dsi_pll_hsdiv_dsi_clk; | ||
4300 | lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk * 2); | ||
4301 | |||
4302 | dssdev->clocks.dsi.regn = cinfo.regn; | ||
4303 | dssdev->clocks.dsi.regm = cinfo.regm; | ||
4304 | dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc; | ||
4305 | dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi; | ||
4306 | |||
4307 | dssdev->clocks.dsi.lp_clk_div = lp_clk_div; | ||
4308 | |||
4309 | dssdev->clocks.dispc.channel.lck_div = dispc_cinfo.lck_div; | ||
4310 | dssdev->clocks.dispc.channel.pck_div = dispc_cinfo.pck_div; | ||
4311 | |||
4312 | dssdev->clocks.dispc.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK; | ||
4313 | |||
4314 | dssdev->clocks.dispc.channel.lcd_clk_src = | ||
4315 | dsi->module_id == 0 ? | ||
4316 | OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC : | ||
4317 | OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC; | ||
4318 | |||
4319 | dssdev->clocks.dsi.dsi_fclk_src = | ||
4320 | dsi->module_id == 0 ? | ||
4321 | OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI : | ||
4322 | OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI; | ||
4323 | |||
4324 | mutex_unlock(&dsi->lock); | ||
4325 | return 0; | ||
4326 | err: | ||
4327 | mutex_unlock(&dsi->lock); | ||
4328 | return r; | ||
4329 | } | ||
4330 | EXPORT_SYMBOL(omapdss_dsi_set_clocks); | ||
4331 | |||
4332 | int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) | ||
4333 | { | ||
4334 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
4335 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4336 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
4337 | int bpp = dsi_get_pixel_size(dsi->pix_fmt); | ||
4107 | u8 data_type; | 4338 | u8 data_type; |
4108 | u16 word_count; | 4339 | u16 word_count; |
4109 | int r; | 4340 | int r; |
4110 | 4341 | ||
4111 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { | 4342 | if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { |
4112 | switch (dssdev->panel.dsi_pix_fmt) { | 4343 | switch (dsi->pix_fmt) { |
4113 | case OMAP_DSS_DSI_FMT_RGB888: | 4344 | case OMAP_DSS_DSI_FMT_RGB888: |
4114 | data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24; | 4345 | data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24; |
4115 | break; | 4346 | break; |
@@ -4133,7 +4364,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) | |||
4133 | /* MODE, 1 = video mode */ | 4364 | /* MODE, 1 = video mode */ |
4134 | REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4); | 4365 | REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4); |
4135 | 4366 | ||
4136 | word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8); | 4367 | word_count = DIV_ROUND_UP(dsi->timings.x_res * bpp, 8); |
4137 | 4368 | ||
4138 | dsi_vc_write_long_header(dsidev, channel, data_type, | 4369 | dsi_vc_write_long_header(dsidev, channel, data_type, |
4139 | word_count, 0); | 4370 | word_count, 0); |
@@ -4142,9 +4373,9 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) | |||
4142 | dsi_if_enable(dsidev, true); | 4373 | dsi_if_enable(dsidev, true); |
4143 | } | 4374 | } |
4144 | 4375 | ||
4145 | r = dss_mgr_enable(dssdev->manager); | 4376 | r = dss_mgr_enable(mgr); |
4146 | if (r) { | 4377 | if (r) { |
4147 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { | 4378 | if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { |
4148 | dsi_if_enable(dsidev, false); | 4379 | dsi_if_enable(dsidev, false); |
4149 | dsi_vc_enable(dsidev, channel, false); | 4380 | dsi_vc_enable(dsidev, channel, false); |
4150 | } | 4381 | } |
@@ -4159,8 +4390,10 @@ EXPORT_SYMBOL(dsi_enable_video_output); | |||
4159 | void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel) | 4390 | void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel) |
4160 | { | 4391 | { |
4161 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4392 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4393 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4394 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
4162 | 4395 | ||
4163 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) { | 4396 | if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { |
4164 | dsi_if_enable(dsidev, false); | 4397 | dsi_if_enable(dsidev, false); |
4165 | dsi_vc_enable(dsidev, channel, false); | 4398 | dsi_vc_enable(dsidev, channel, false); |
4166 | 4399 | ||
@@ -4171,15 +4404,15 @@ void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel) | |||
4171 | dsi_if_enable(dsidev, true); | 4404 | dsi_if_enable(dsidev, true); |
4172 | } | 4405 | } |
4173 | 4406 | ||
4174 | dss_mgr_disable(dssdev->manager); | 4407 | dss_mgr_disable(mgr); |
4175 | } | 4408 | } |
4176 | EXPORT_SYMBOL(dsi_disable_video_output); | 4409 | EXPORT_SYMBOL(dsi_disable_video_output); |
4177 | 4410 | ||
4178 | static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, | 4411 | static void dsi_update_screen_dispc(struct omap_dss_device *dssdev) |
4179 | u16 w, u16 h) | ||
4180 | { | 4412 | { |
4181 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4413 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4182 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4414 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
4415 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
4183 | unsigned bytespp; | 4416 | unsigned bytespp; |
4184 | unsigned bytespl; | 4417 | unsigned bytespl; |
4185 | unsigned bytespf; | 4418 | unsigned bytespf; |
@@ -4190,12 +4423,14 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, | |||
4190 | int r; | 4423 | int r; |
4191 | const unsigned channel = dsi->update_channel; | 4424 | const unsigned channel = dsi->update_channel; |
4192 | const unsigned line_buf_size = dsi_get_line_buf_size(dsidev); | 4425 | const unsigned line_buf_size = dsi_get_line_buf_size(dsidev); |
4426 | u16 w = dsi->timings.x_res; | ||
4427 | u16 h = dsi->timings.y_res; | ||
4193 | 4428 | ||
4194 | DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h); | 4429 | DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h); |
4195 | 4430 | ||
4196 | dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_VP); | 4431 | dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_VP); |
4197 | 4432 | ||
4198 | bytespp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8; | 4433 | bytespp = dsi_get_pixel_size(dsi->pix_fmt) / 8; |
4199 | bytespl = w * bytespp; | 4434 | bytespl = w * bytespp; |
4200 | bytespf = bytespl * h; | 4435 | bytespf = bytespl * h; |
4201 | 4436 | ||
@@ -4239,7 +4474,9 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, | |||
4239 | msecs_to_jiffies(250)); | 4474 | msecs_to_jiffies(250)); |
4240 | BUG_ON(r == 0); | 4475 | BUG_ON(r == 0); |
4241 | 4476 | ||
4242 | dss_mgr_start_update(dssdev->manager); | 4477 | dss_mgr_set_timings(mgr, &dsi->timings); |
4478 | |||
4479 | dss_mgr_start_update(mgr); | ||
4243 | 4480 | ||
4244 | if (dsi->te_enabled) { | 4481 | if (dsi->te_enabled) { |
4245 | /* disable LP_RX_TO, so that we can receive TE. Time to wait | 4482 | /* disable LP_RX_TO, so that we can receive TE. Time to wait |
@@ -4297,8 +4534,7 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work) | |||
4297 | 4534 | ||
4298 | static void dsi_framedone_irq_callback(void *data, u32 mask) | 4535 | static void dsi_framedone_irq_callback(void *data, u32 mask) |
4299 | { | 4536 | { |
4300 | struct omap_dss_device *dssdev = (struct omap_dss_device *) data; | 4537 | struct platform_device *dsidev = (struct platform_device *) data; |
4301 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
4302 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4538 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
4303 | 4539 | ||
4304 | /* Note: We get FRAMEDONE when DISPC has finished sending pixels and | 4540 | /* Note: We get FRAMEDONE when DISPC has finished sending pixels and |
@@ -4325,13 +4561,14 @@ int omap_dsi_update(struct omap_dss_device *dssdev, int channel, | |||
4325 | dsi->framedone_callback = callback; | 4561 | dsi->framedone_callback = callback; |
4326 | dsi->framedone_data = data; | 4562 | dsi->framedone_data = data; |
4327 | 4563 | ||
4328 | dssdev->driver->get_resolution(dssdev, &dw, &dh); | 4564 | dw = dsi->timings.x_res; |
4565 | dh = dsi->timings.y_res; | ||
4329 | 4566 | ||
4330 | #ifdef DEBUG | 4567 | #ifdef DEBUG |
4331 | dsi->update_bytes = dw * dh * | 4568 | dsi->update_bytes = dw * dh * |
4332 | dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8; | 4569 | dsi_get_pixel_size(dsi->pix_fmt) / 8; |
4333 | #endif | 4570 | #endif |
4334 | dsi_update_screen_dispc(dssdev, dw, dh); | 4571 | dsi_update_screen_dispc(dssdev); |
4335 | 4572 | ||
4336 | return 0; | 4573 | return 0; |
4337 | } | 4574 | } |
@@ -4367,28 +4604,22 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) | |||
4367 | { | 4604 | { |
4368 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4605 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4369 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4606 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
4370 | struct omap_video_timings timings; | 4607 | struct omap_overlay_manager *mgr = dssdev->output->manager; |
4371 | int r; | 4608 | int r; |
4372 | u32 irq = 0; | 4609 | u32 irq = 0; |
4373 | 4610 | ||
4374 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) { | 4611 | if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { |
4375 | u16 dw, dh; | 4612 | dsi->timings.hsw = 1; |
4376 | 4613 | dsi->timings.hfp = 1; | |
4377 | dssdev->driver->get_resolution(dssdev, &dw, &dh); | 4614 | dsi->timings.hbp = 1; |
4378 | 4615 | dsi->timings.vsw = 1; | |
4379 | timings.x_res = dw; | 4616 | dsi->timings.vfp = 0; |
4380 | timings.y_res = dh; | 4617 | dsi->timings.vbp = 0; |
4381 | timings.hsw = 1; | ||
4382 | timings.hfp = 1; | ||
4383 | timings.hbp = 1; | ||
4384 | timings.vsw = 1; | ||
4385 | timings.vfp = 0; | ||
4386 | timings.vbp = 0; | ||
4387 | 4618 | ||
4388 | irq = dispc_mgr_get_framedone_irq(dssdev->manager->id); | 4619 | irq = dispc_mgr_get_framedone_irq(mgr->id); |
4389 | 4620 | ||
4390 | r = omap_dispc_register_isr(dsi_framedone_irq_callback, | 4621 | r = omap_dispc_register_isr(dsi_framedone_irq_callback, |
4391 | (void *) dssdev, irq); | 4622 | (void *) dsidev, irq); |
4392 | if (r) { | 4623 | if (r) { |
4393 | DSSERR("can't get FRAMEDONE irq\n"); | 4624 | DSSERR("can't get FRAMEDONE irq\n"); |
4394 | goto err; | 4625 | goto err; |
@@ -4397,8 +4628,6 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) | |||
4397 | dsi->mgr_config.stallmode = true; | 4628 | dsi->mgr_config.stallmode = true; |
4398 | dsi->mgr_config.fifohandcheck = true; | 4629 | dsi->mgr_config.fifohandcheck = true; |
4399 | } else { | 4630 | } else { |
4400 | timings = dssdev->panel.timings; | ||
4401 | |||
4402 | dsi->mgr_config.stallmode = false; | 4631 | dsi->mgr_config.stallmode = false; |
4403 | dsi->mgr_config.fifohandcheck = false; | 4632 | dsi->mgr_config.fifohandcheck = false; |
4404 | } | 4633 | } |
@@ -4407,14 +4636,14 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) | |||
4407 | * override interlace, logic level and edge related parameters in | 4636 | * override interlace, logic level and edge related parameters in |
4408 | * omap_video_timings with default values | 4637 | * omap_video_timings with default values |
4409 | */ | 4638 | */ |
4410 | timings.interlace = false; | 4639 | dsi->timings.interlace = false; |
4411 | timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH; | 4640 | dsi->timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH; |
4412 | timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH; | 4641 | dsi->timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH; |
4413 | timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; | 4642 | dsi->timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; |
4414 | timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH; | 4643 | dsi->timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH; |
4415 | timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; | 4644 | dsi->timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; |
4416 | 4645 | ||
4417 | dss_mgr_set_timings(dssdev->manager, &timings); | 4646 | dss_mgr_set_timings(mgr, &dsi->timings); |
4418 | 4647 | ||
4419 | r = dsi_configure_dispc_clocks(dssdev); | 4648 | r = dsi_configure_dispc_clocks(dssdev); |
4420 | if (r) | 4649 | if (r) |
@@ -4422,29 +4651,33 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) | |||
4422 | 4651 | ||
4423 | dsi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; | 4652 | dsi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; |
4424 | dsi->mgr_config.video_port_width = | 4653 | dsi->mgr_config.video_port_width = |
4425 | dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt); | 4654 | dsi_get_pixel_size(dsi->pix_fmt); |
4426 | dsi->mgr_config.lcden_sig_polarity = 0; | 4655 | dsi->mgr_config.lcden_sig_polarity = 0; |
4427 | 4656 | ||
4428 | dss_mgr_set_lcd_config(dssdev->manager, &dsi->mgr_config); | 4657 | dss_mgr_set_lcd_config(mgr, &dsi->mgr_config); |
4429 | 4658 | ||
4430 | return 0; | 4659 | return 0; |
4431 | err1: | 4660 | err1: |
4432 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) | 4661 | if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) |
4433 | omap_dispc_unregister_isr(dsi_framedone_irq_callback, | 4662 | omap_dispc_unregister_isr(dsi_framedone_irq_callback, |
4434 | (void *) dssdev, irq); | 4663 | (void *) dsidev, irq); |
4435 | err: | 4664 | err: |
4436 | return r; | 4665 | return r; |
4437 | } | 4666 | } |
4438 | 4667 | ||
4439 | static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) | 4668 | static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) |
4440 | { | 4669 | { |
4441 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) { | 4670 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4671 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4672 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
4673 | |||
4674 | if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { | ||
4442 | u32 irq; | 4675 | u32 irq; |
4443 | 4676 | ||
4444 | irq = dispc_mgr_get_framedone_irq(dssdev->manager->id); | 4677 | irq = dispc_mgr_get_framedone_irq(mgr->id); |
4445 | 4678 | ||
4446 | omap_dispc_unregister_isr(dsi_framedone_irq_callback, | 4679 | omap_dispc_unregister_isr(dsi_framedone_irq_callback, |
4447 | (void *) dssdev, irq); | 4680 | (void *) dsidev, irq); |
4448 | } | 4681 | } |
4449 | } | 4682 | } |
4450 | 4683 | ||
@@ -4477,6 +4710,7 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) | |||
4477 | { | 4710 | { |
4478 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4711 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4479 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4712 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
4713 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
4480 | int r; | 4714 | int r; |
4481 | 4715 | ||
4482 | r = dsi_pll_init(dsidev, true, true); | 4716 | r = dsi_pll_init(dsidev, true, true); |
@@ -4489,18 +4723,18 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) | |||
4489 | 4723 | ||
4490 | dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); | 4724 | dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); |
4491 | dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src); | 4725 | dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src); |
4492 | dss_select_lcd_clk_source(dssdev->manager->id, | 4726 | dss_select_lcd_clk_source(mgr->id, |
4493 | dssdev->clocks.dispc.channel.lcd_clk_src); | 4727 | dssdev->clocks.dispc.channel.lcd_clk_src); |
4494 | 4728 | ||
4495 | DSSDBG("PLL OK\n"); | 4729 | DSSDBG("PLL OK\n"); |
4496 | 4730 | ||
4497 | r = dsi_cio_init(dssdev); | 4731 | r = dsi_cio_init(dsidev); |
4498 | if (r) | 4732 | if (r) |
4499 | goto err2; | 4733 | goto err2; |
4500 | 4734 | ||
4501 | _dsi_print_reset_status(dsidev); | 4735 | _dsi_print_reset_status(dsidev); |
4502 | 4736 | ||
4503 | dsi_proto_timings(dssdev); | 4737 | dsi_proto_timings(dsidev); |
4504 | dsi_set_lp_clk_divisor(dssdev); | 4738 | dsi_set_lp_clk_divisor(dssdev); |
4505 | 4739 | ||
4506 | if (1) | 4740 | if (1) |
@@ -4520,11 +4754,11 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) | |||
4520 | 4754 | ||
4521 | return 0; | 4755 | return 0; |
4522 | err3: | 4756 | err3: |
4523 | dsi_cio_uninit(dssdev); | 4757 | dsi_cio_uninit(dsidev); |
4524 | err2: | 4758 | err2: |
4525 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); | 4759 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); |
4526 | dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); | 4760 | dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); |
4527 | dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK); | 4761 | dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); |
4528 | 4762 | ||
4529 | err1: | 4763 | err1: |
4530 | dsi_pll_uninit(dsidev, true); | 4764 | dsi_pll_uninit(dsidev, true); |
@@ -4537,6 +4771,7 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev, | |||
4537 | { | 4771 | { |
4538 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4772 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4539 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4773 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
4774 | struct omap_overlay_manager *mgr = dssdev->output->manager; | ||
4540 | 4775 | ||
4541 | if (enter_ulps && !dsi->ulps_enabled) | 4776 | if (enter_ulps && !dsi->ulps_enabled) |
4542 | dsi_enter_ulps(dsidev); | 4777 | dsi_enter_ulps(dsidev); |
@@ -4550,8 +4785,8 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev, | |||
4550 | 4785 | ||
4551 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); | 4786 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); |
4552 | dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); | 4787 | dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); |
4553 | dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK); | 4788 | dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); |
4554 | dsi_cio_uninit(dssdev); | 4789 | dsi_cio_uninit(dsidev); |
4555 | dsi_pll_uninit(dsidev, disconnect_lanes); | 4790 | dsi_pll_uninit(dsidev, disconnect_lanes); |
4556 | } | 4791 | } |
4557 | 4792 | ||
@@ -4559,6 +4794,7 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) | |||
4559 | { | 4794 | { |
4560 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4795 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4561 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4796 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
4797 | struct omap_dss_output *out = dssdev->output; | ||
4562 | int r = 0; | 4798 | int r = 0; |
4563 | 4799 | ||
4564 | DSSDBG("dsi_display_enable\n"); | 4800 | DSSDBG("dsi_display_enable\n"); |
@@ -4567,8 +4803,8 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) | |||
4567 | 4803 | ||
4568 | mutex_lock(&dsi->lock); | 4804 | mutex_lock(&dsi->lock); |
4569 | 4805 | ||
4570 | if (dssdev->manager == NULL) { | 4806 | if (out == NULL || out->manager == NULL) { |
4571 | DSSERR("failed to enable display: no manager\n"); | 4807 | DSSERR("failed to enable display: no output/manager\n"); |
4572 | r = -ENODEV; | 4808 | r = -ENODEV; |
4573 | goto err_start_dev; | 4809 | goto err_start_dev; |
4574 | } | 4810 | } |
@@ -4653,17 +4889,83 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) | |||
4653 | } | 4889 | } |
4654 | EXPORT_SYMBOL(omapdss_dsi_enable_te); | 4890 | EXPORT_SYMBOL(omapdss_dsi_enable_te); |
4655 | 4891 | ||
4656 | static int __init dsi_init_display(struct omap_dss_device *dssdev) | 4892 | void omapdss_dsi_set_timings(struct omap_dss_device *dssdev, |
4893 | struct omap_video_timings *timings) | ||
4657 | { | 4894 | { |
4658 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 4895 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4659 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 4896 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
4660 | 4897 | ||
4661 | DSSDBG("DSI init\n"); | 4898 | mutex_lock(&dsi->lock); |
4662 | 4899 | ||
4663 | if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) { | 4900 | dsi->timings = *timings; |
4664 | dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | | 4901 | |
4665 | OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; | 4902 | mutex_unlock(&dsi->lock); |
4666 | } | 4903 | } |
4904 | EXPORT_SYMBOL(omapdss_dsi_set_timings); | ||
4905 | |||
4906 | void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h) | ||
4907 | { | ||
4908 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
4909 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4910 | |||
4911 | mutex_lock(&dsi->lock); | ||
4912 | |||
4913 | dsi->timings.x_res = w; | ||
4914 | dsi->timings.y_res = h; | ||
4915 | |||
4916 | mutex_unlock(&dsi->lock); | ||
4917 | } | ||
4918 | EXPORT_SYMBOL(omapdss_dsi_set_size); | ||
4919 | |||
4920 | void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev, | ||
4921 | enum omap_dss_dsi_pixel_format fmt) | ||
4922 | { | ||
4923 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
4924 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4925 | |||
4926 | mutex_lock(&dsi->lock); | ||
4927 | |||
4928 | dsi->pix_fmt = fmt; | ||
4929 | |||
4930 | mutex_unlock(&dsi->lock); | ||
4931 | } | ||
4932 | EXPORT_SYMBOL(omapdss_dsi_set_pixel_format); | ||
4933 | |||
4934 | void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev, | ||
4935 | enum omap_dss_dsi_mode mode) | ||
4936 | { | ||
4937 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
4938 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4939 | |||
4940 | mutex_lock(&dsi->lock); | ||
4941 | |||
4942 | dsi->mode = mode; | ||
4943 | |||
4944 | mutex_unlock(&dsi->lock); | ||
4945 | } | ||
4946 | EXPORT_SYMBOL(omapdss_dsi_set_operation_mode); | ||
4947 | |||
4948 | void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev, | ||
4949 | struct omap_dss_dsi_videomode_timings *timings) | ||
4950 | { | ||
4951 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
4952 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4953 | |||
4954 | mutex_lock(&dsi->lock); | ||
4955 | |||
4956 | dsi->vm_timings = *timings; | ||
4957 | |||
4958 | mutex_unlock(&dsi->lock); | ||
4959 | } | ||
4960 | EXPORT_SYMBOL(omapdss_dsi_set_videomode_timings); | ||
4961 | |||
4962 | static int __init dsi_init_display(struct omap_dss_device *dssdev) | ||
4963 | { | ||
4964 | struct platform_device *dsidev = | ||
4965 | dsi_get_dsidev_from_id(dssdev->phy.dsi.module); | ||
4966 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4967 | |||
4968 | DSSDBG("DSI init\n"); | ||
4667 | 4969 | ||
4668 | if (dsi->vdds_dsi_reg == NULL) { | 4970 | if (dsi->vdds_dsi_reg == NULL) { |
4669 | struct regulator *vdds_dsi; | 4971 | struct regulator *vdds_dsi; |
@@ -4806,11 +5108,15 @@ static void dsi_put_clocks(struct platform_device *dsidev) | |||
4806 | clk_put(dsi->sys_clk); | 5108 | clk_put(dsi->sys_clk); |
4807 | } | 5109 | } |
4808 | 5110 | ||
4809 | static void __init dsi_probe_pdata(struct platform_device *dsidev) | 5111 | static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *pdev) |
4810 | { | 5112 | { |
4811 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 5113 | struct omap_dss_board_info *pdata = pdev->dev.platform_data; |
4812 | struct omap_dss_board_info *pdata = dsidev->dev.platform_data; | 5114 | struct dsi_data *dsi = dsi_get_dsidrv_data(pdev); |
4813 | int i, r; | 5115 | const char *def_disp_name = dss_get_default_display_name(); |
5116 | struct omap_dss_device *def_dssdev; | ||
5117 | int i; | ||
5118 | |||
5119 | def_dssdev = NULL; | ||
4814 | 5120 | ||
4815 | for (i = 0; i < pdata->num_devices; ++i) { | 5121 | for (i = 0; i < pdata->num_devices; ++i) { |
4816 | struct omap_dss_device *dssdev = pdata->devices[i]; | 5122 | struct omap_dss_device *dssdev = pdata->devices[i]; |
@@ -4821,19 +5127,73 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev) | |||
4821 | if (dssdev->phy.dsi.module != dsi->module_id) | 5127 | if (dssdev->phy.dsi.module != dsi->module_id) |
4822 | continue; | 5128 | continue; |
4823 | 5129 | ||
4824 | r = dsi_init_display(dssdev); | 5130 | if (def_dssdev == NULL) |
4825 | if (r) { | 5131 | def_dssdev = dssdev; |
4826 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | 5132 | |
4827 | continue; | 5133 | if (def_disp_name != NULL && |
5134 | strcmp(dssdev->name, def_disp_name) == 0) { | ||
5135 | def_dssdev = dssdev; | ||
5136 | break; | ||
4828 | } | 5137 | } |
5138 | } | ||
4829 | 5139 | ||
4830 | r = omap_dss_register_device(dssdev, &dsidev->dev, i); | 5140 | return def_dssdev; |
4831 | if (r) | 5141 | } |
4832 | DSSERR("device %s register failed: %d\n", | 5142 | |
4833 | dssdev->name, r); | 5143 | static void __init dsi_probe_pdata(struct platform_device *dsidev) |
5144 | { | ||
5145 | struct omap_dss_device *plat_dssdev; | ||
5146 | struct omap_dss_device *dssdev; | ||
5147 | int r; | ||
5148 | |||
5149 | plat_dssdev = dsi_find_dssdev(dsidev); | ||
5150 | |||
5151 | if (!plat_dssdev) | ||
5152 | return; | ||
5153 | |||
5154 | dssdev = dss_alloc_and_init_device(&dsidev->dev); | ||
5155 | if (!dssdev) | ||
5156 | return; | ||
5157 | |||
5158 | dss_copy_device_pdata(dssdev, plat_dssdev); | ||
5159 | |||
5160 | r = dsi_init_display(dssdev); | ||
5161 | if (r) { | ||
5162 | DSSERR("device %s init failed: %d\n", dssdev->name, r); | ||
5163 | dss_put_device(dssdev); | ||
5164 | return; | ||
5165 | } | ||
5166 | |||
5167 | r = dss_add_device(dssdev); | ||
5168 | if (r) { | ||
5169 | DSSERR("device %s register failed: %d\n", dssdev->name, r); | ||
5170 | dss_put_device(dssdev); | ||
5171 | return; | ||
4834 | } | 5172 | } |
4835 | } | 5173 | } |
4836 | 5174 | ||
5175 | static void __init dsi_init_output(struct platform_device *dsidev) | ||
5176 | { | ||
5177 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
5178 | struct omap_dss_output *out = &dsi->output; | ||
5179 | |||
5180 | out->pdev = dsidev; | ||
5181 | out->id = dsi->module_id == 0 ? | ||
5182 | OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; | ||
5183 | |||
5184 | out->type = OMAP_DISPLAY_TYPE_DSI; | ||
5185 | |||
5186 | dss_register_output(out); | ||
5187 | } | ||
5188 | |||
5189 | static void __exit dsi_uninit_output(struct platform_device *dsidev) | ||
5190 | { | ||
5191 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
5192 | struct omap_dss_output *out = &dsi->output; | ||
5193 | |||
5194 | dss_unregister_output(out); | ||
5195 | } | ||
5196 | |||
4837 | /* DSI1 HW IP initialisation */ | 5197 | /* DSI1 HW IP initialisation */ |
4838 | static int __init omap_dsihw_probe(struct platform_device *dsidev) | 5198 | static int __init omap_dsihw_probe(struct platform_device *dsidev) |
4839 | { | 5199 | { |
@@ -4848,7 +5208,6 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev) | |||
4848 | 5208 | ||
4849 | dsi->module_id = dsidev->id; | 5209 | dsi->module_id = dsidev->id; |
4850 | dsi->pdev = dsidev; | 5210 | dsi->pdev = dsidev; |
4851 | dsi_pdev_map[dsi->module_id] = dsidev; | ||
4852 | dev_set_drvdata(&dsidev->dev, dsi); | 5211 | dev_set_drvdata(&dsidev->dev, dsi); |
4853 | 5212 | ||
4854 | spin_lock_init(&dsi->irq_lock); | 5213 | spin_lock_init(&dsi->irq_lock); |
@@ -4928,6 +5287,8 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev) | |||
4928 | else | 5287 | else |
4929 | dsi->num_lanes_supported = 3; | 5288 | dsi->num_lanes_supported = 3; |
4930 | 5289 | ||
5290 | dsi_init_output(dsidev); | ||
5291 | |||
4931 | dsi_probe_pdata(dsidev); | 5292 | dsi_probe_pdata(dsidev); |
4932 | 5293 | ||
4933 | dsi_runtime_put(dsidev); | 5294 | dsi_runtime_put(dsidev); |
@@ -4957,7 +5318,9 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev) | |||
4957 | 5318 | ||
4958 | WARN_ON(dsi->scp_clk_refcount > 0); | 5319 | WARN_ON(dsi->scp_clk_refcount > 0); |
4959 | 5320 | ||
4960 | omap_dss_unregister_child_devices(&dsidev->dev); | 5321 | dss_unregister_child_devices(&dsidev->dev); |
5322 | |||
5323 | dsi_uninit_output(dsidev); | ||
4961 | 5324 | ||
4962 | pm_runtime_disable(&dsidev->dev); | 5325 | pm_runtime_disable(&dsidev->dev); |
4963 | 5326 | ||