diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-09-25 04:26:28 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2012-09-25 04:26:28 -0400 |
commit | 406f7b8baa8f92d88dac448a9dc0dbeb3e330874 (patch) | |
tree | 9abc90f8338cb2c886e263d64a1d6fe8f389ee3d /drivers/video | |
parent | c0ca7c38c5d35c12a9b94ef42842b325dfd2a3cd (diff) | |
parent | 995885897ff0ef3dad12fcfbfd0c26e185bf4ac0 (diff) |
Merge OMAP5 DSS changes to omapdss
This series adds basic OMAP5 DSS functionality, mainly related to DSS core, DPI
and DSI.
* omap5-dss:
OMAPDSS: DSI: make OMAP2_DSS_DSI depend on ARCH_OMAP5
OMAPDSS: DSI: Add code to disable PHY DCC
OMAPDSS: DSI: Add new linebuffer size for OMAP5
OMAPDSS: DSI: Add FEAT_DSI_PLL_REFSEL
OMAPDSS: DSI: Add FEAT_DSI_PLL_SELFREQDCO
OMAPDSS: Add support for DPI source selection
OMAPDSS: move dss feats to the end of dss.c
OMAPDSS: Add basic omap5 features to dss and dispc
OMAPDSS: DSI: improve DSI clock calcs for DISPC
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/omap2/dss/Kconfig | 2 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 2 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dpi.c | 5 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 167 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.c | 121 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.h | 1 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.c | 96 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.h | 3 |
8 files changed, 337 insertions, 60 deletions
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig index b337a8469fd8..80f5390aa136 100644 --- a/drivers/video/omap2/dss/Kconfig +++ b/drivers/video/omap2/dss/Kconfig | |||
@@ -84,7 +84,7 @@ config OMAP2_DSS_SDI | |||
84 | 84 | ||
85 | config OMAP2_DSS_DSI | 85 | config OMAP2_DSS_DSI |
86 | bool "DSI support" | 86 | bool "DSI support" |
87 | depends on ARCH_OMAP3 || ARCH_OMAP4 | 87 | depends on ARCH_OMAP3 || ARCH_OMAP4 || ARCH_OMAP5 |
88 | default n | 88 | default n |
89 | help | 89 | help |
90 | MIPI DSI (Display Serial Interface) support. | 90 | MIPI DSI (Display Serial Interface) support. |
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index d512c389741e..e52c57789383 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
@@ -3829,6 +3829,8 @@ static int __init dispc_init_features(struct device *dev) | |||
3829 | src = &omap34xx_rev3_0_dispc_feats; | 3829 | src = &omap34xx_rev3_0_dispc_feats; |
3830 | } else if (cpu_is_omap44xx()) { | 3830 | } else if (cpu_is_omap44xx()) { |
3831 | src = &omap44xx_dispc_feats; | 3831 | src = &omap44xx_dispc_feats; |
3832 | } else if (soc_is_omap54xx()) { | ||
3833 | src = &omap44xx_dispc_feats; | ||
3832 | } else { | 3834 | } else { |
3833 | return -ENODEV; | 3835 | return -ENODEV; |
3834 | } | 3836 | } |
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index fac19d39ab18..f6800e19bbcb 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c | |||
@@ -203,6 +203,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) | |||
203 | if (r) | 203 | if (r) |
204 | goto err_get_dispc; | 204 | goto err_get_dispc; |
205 | 205 | ||
206 | r = dss_dpi_select_source(dssdev->channel); | ||
207 | if (r) | ||
208 | goto err_src_sel; | ||
209 | |||
206 | if (dpi_use_dsi_pll(dssdev)) { | 210 | if (dpi_use_dsi_pll(dssdev)) { |
207 | r = dsi_runtime_get(dpi.dsidev); | 211 | r = dsi_runtime_get(dpi.dsidev); |
208 | if (r) | 212 | if (r) |
@@ -237,6 +241,7 @@ err_dsi_pll_init: | |||
237 | if (dpi_use_dsi_pll(dssdev)) | 241 | if (dpi_use_dsi_pll(dssdev)) |
238 | dsi_runtime_put(dpi.dsidev); | 242 | dsi_runtime_put(dpi.dsidev); |
239 | err_get_dsi: | 243 | err_get_dsi: |
244 | err_src_sel: | ||
240 | dispc_runtime_put(); | 245 | dispc_runtime_put(); |
241 | err_get_dispc: | 246 | err_get_dispc: |
242 | if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) | 247 | if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) |
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 1dd019cf9649..4d748139315d 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c | |||
@@ -1454,26 +1454,17 @@ found: | |||
1454 | } | 1454 | } |
1455 | 1455 | ||
1456 | static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev, | 1456 | static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev, |
1457 | unsigned long req_clk, struct dsi_clock_info *cinfo) | 1457 | unsigned long req_clkin4ddr, struct dsi_clock_info *cinfo) |
1458 | { | 1458 | { |
1459 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | 1459 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
1460 | struct dsi_clock_info cur, best; | 1460 | struct dsi_clock_info cur, best; |
1461 | unsigned long dss_sys_clk, max_dss_fck, max_dsi_fck; | ||
1462 | unsigned long req_clkin4ddr; | ||
1463 | 1461 | ||
1464 | DSSDBG("dsi_pll_calc_ddrfreq\n"); | 1462 | DSSDBG("dsi_pll_calc_ddrfreq\n"); |
1465 | 1463 | ||
1466 | dss_sys_clk = clk_get_rate(dsi->sys_clk); | ||
1467 | |||
1468 | max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); | ||
1469 | max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK); | ||
1470 | |||
1471 | memset(&best, 0, sizeof(best)); | 1464 | memset(&best, 0, sizeof(best)); |
1472 | memset(&cur, 0, sizeof(cur)); | 1465 | memset(&cur, 0, sizeof(cur)); |
1473 | 1466 | ||
1474 | cur.clkin = dss_sys_clk; | 1467 | cur.clkin = clk_get_rate(dsi->sys_clk); |
1475 | |||
1476 | req_clkin4ddr = req_clk * 4; | ||
1477 | 1468 | ||
1478 | for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) { | 1469 | for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) { |
1479 | cur.fint = cur.clkin / cur.regn; | 1470 | cur.fint = cur.clkin / cur.regn; |
@@ -1503,18 +1494,107 @@ static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev, | |||
1503 | } | 1494 | } |
1504 | } | 1495 | } |
1505 | found: | 1496 | found: |
1506 | best.regm_dispc = DIV_ROUND_UP(best.clkin4ddr, max_dss_fck); | ||
1507 | best.dsi_pll_hsdiv_dispc_clk = best.clkin4ddr / best.regm_dispc; | ||
1508 | |||
1509 | best.regm_dsi = DIV_ROUND_UP(best.clkin4ddr, max_dsi_fck); | ||
1510 | best.dsi_pll_hsdiv_dsi_clk = best.clkin4ddr / best.regm_dsi; | ||
1511 | |||
1512 | if (cinfo) | 1497 | if (cinfo) |
1513 | *cinfo = best; | 1498 | *cinfo = best; |
1514 | 1499 | ||
1515 | return 0; | 1500 | return 0; |
1516 | } | 1501 | } |
1517 | 1502 | ||
1503 | static void dsi_pll_calc_dsi_fck(struct platform_device *dsidev, | ||
1504 | struct dsi_clock_info *cinfo) | ||
1505 | { | ||
1506 | unsigned long max_dsi_fck; | ||
1507 | |||
1508 | max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK); | ||
1509 | |||
1510 | cinfo->regm_dsi = DIV_ROUND_UP(cinfo->clkin4ddr, max_dsi_fck); | ||
1511 | cinfo->dsi_pll_hsdiv_dsi_clk = cinfo->clkin4ddr / cinfo->regm_dsi; | ||
1512 | } | ||
1513 | |||
1514 | static int dsi_pll_calc_dispc_fck(struct platform_device *dsidev, | ||
1515 | unsigned long req_pck, struct dsi_clock_info *cinfo, | ||
1516 | struct dispc_clock_info *dispc_cinfo) | ||
1517 | { | ||
1518 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1519 | unsigned regm_dispc, best_regm_dispc; | ||
1520 | unsigned long dispc_clk, best_dispc_clk; | ||
1521 | int min_fck_per_pck; | ||
1522 | unsigned long max_dss_fck; | ||
1523 | struct dispc_clock_info best_dispc; | ||
1524 | bool match; | ||
1525 | |||
1526 | max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); | ||
1527 | |||
1528 | min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; | ||
1529 | |||
1530 | if (min_fck_per_pck && | ||
1531 | req_pck * min_fck_per_pck > max_dss_fck) { | ||
1532 | DSSERR("Requested pixel clock not possible with the current " | ||
1533 | "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " | ||
1534 | "the constraint off.\n"); | ||
1535 | min_fck_per_pck = 0; | ||
1536 | } | ||
1537 | |||
1538 | retry: | ||
1539 | best_regm_dispc = 0; | ||
1540 | best_dispc_clk = 0; | ||
1541 | memset(&best_dispc, 0, sizeof(best_dispc)); | ||
1542 | match = false; | ||
1543 | |||
1544 | for (regm_dispc = 1; regm_dispc < dsi->regm_dispc_max; ++regm_dispc) { | ||
1545 | struct dispc_clock_info cur_dispc; | ||
1546 | |||
1547 | dispc_clk = cinfo->clkin4ddr / regm_dispc; | ||
1548 | |||
1549 | /* this will narrow down the search a bit, | ||
1550 | * but still give pixclocks below what was | ||
1551 | * requested */ | ||
1552 | if (dispc_clk < req_pck) | ||
1553 | break; | ||
1554 | |||
1555 | if (dispc_clk > max_dss_fck) | ||
1556 | continue; | ||
1557 | |||
1558 | if (min_fck_per_pck && dispc_clk < req_pck * min_fck_per_pck) | ||
1559 | continue; | ||
1560 | |||
1561 | match = true; | ||
1562 | |||
1563 | dispc_find_clk_divs(req_pck, dispc_clk, &cur_dispc); | ||
1564 | |||
1565 | if (abs(cur_dispc.pck - req_pck) < | ||
1566 | abs(best_dispc.pck - req_pck)) { | ||
1567 | best_regm_dispc = regm_dispc; | ||
1568 | best_dispc_clk = dispc_clk; | ||
1569 | best_dispc = cur_dispc; | ||
1570 | |||
1571 | if (cur_dispc.pck == req_pck) | ||
1572 | goto found; | ||
1573 | } | ||
1574 | } | ||
1575 | |||
1576 | if (!match) { | ||
1577 | if (min_fck_per_pck) { | ||
1578 | DSSERR("Could not find suitable clock settings.\n" | ||
1579 | "Turning FCK/PCK constraint off and" | ||
1580 | "trying again.\n"); | ||
1581 | min_fck_per_pck = 0; | ||
1582 | goto retry; | ||
1583 | } | ||
1584 | |||
1585 | DSSERR("Could not find suitable clock settings.\n"); | ||
1586 | |||
1587 | return -EINVAL; | ||
1588 | } | ||
1589 | found: | ||
1590 | cinfo->regm_dispc = best_regm_dispc; | ||
1591 | cinfo->dsi_pll_hsdiv_dispc_clk = best_dispc_clk; | ||
1592 | |||
1593 | *dispc_cinfo = best_dispc; | ||
1594 | |||
1595 | return 0; | ||
1596 | } | ||
1597 | |||
1518 | int dsi_pll_set_clock_div(struct platform_device *dsidev, | 1598 | int dsi_pll_set_clock_div(struct platform_device *dsidev, |
1519 | struct dsi_clock_info *cinfo) | 1599 | struct dsi_clock_info *cinfo) |
1520 | { | 1600 | { |
@@ -1591,21 +1671,27 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev, | |||
1591 | 1671 | ||
1592 | BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max); | 1672 | BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max); |
1593 | 1673 | ||
1674 | l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2); | ||
1675 | |||
1594 | if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) { | 1676 | if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) { |
1595 | f = cinfo->fint < 1000000 ? 0x3 : | 1677 | f = cinfo->fint < 1000000 ? 0x3 : |
1596 | cinfo->fint < 1250000 ? 0x4 : | 1678 | cinfo->fint < 1250000 ? 0x4 : |
1597 | cinfo->fint < 1500000 ? 0x5 : | 1679 | cinfo->fint < 1500000 ? 0x5 : |
1598 | cinfo->fint < 1750000 ? 0x6 : | 1680 | cinfo->fint < 1750000 ? 0x6 : |
1599 | 0x7; | 1681 | 0x7; |
1600 | } | ||
1601 | 1682 | ||
1602 | l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2); | ||
1603 | |||
1604 | if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) | ||
1605 | l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ | 1683 | l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ |
1684 | } else if (dss_has_feature(FEAT_DSI_PLL_SELFREQDCO)) { | ||
1685 | f = cinfo->clkin4ddr < 1000000000 ? 0x2 : 0x4; | ||
1686 | |||
1687 | l = FLD_MOD(l, f, 4, 1); /* PLL_SELFREQDCO */ | ||
1688 | } | ||
1689 | |||
1606 | l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ | 1690 | l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ |
1607 | l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ | 1691 | l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ |
1608 | l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ | 1692 | l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ |
1693 | if (dss_has_feature(FEAT_DSI_PLL_REFSEL)) | ||
1694 | l = FLD_MOD(l, 3, 22, 21); /* REF_SYSCLK = sysclk */ | ||
1609 | dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l); | 1695 | dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l); |
1610 | 1696 | ||
1611 | REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */ | 1697 | REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */ |
@@ -2069,6 +2155,8 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev) | |||
2069 | return 1194 * 3; /* 1194x24 bits */ | 2155 | return 1194 * 3; /* 1194x24 bits */ |
2070 | case 6: | 2156 | case 6: |
2071 | return 1365 * 3; /* 1365x24 bits */ | 2157 | return 1365 * 3; /* 1365x24 bits */ |
2158 | case 7: | ||
2159 | return 1920 * 3; /* 1920x24 bits */ | ||
2072 | default: | 2160 | default: |
2073 | BUG(); | 2161 | BUG(); |
2074 | return 0; | 2162 | return 0; |
@@ -2204,6 +2292,13 @@ static void dsi_cio_timings(struct platform_device *dsidev) | |||
2204 | r = FLD_MOD(r, tlpx_half, 22, 16); | 2292 | r = FLD_MOD(r, tlpx_half, 22, 16); |
2205 | r = FLD_MOD(r, tclk_trail, 15, 8); | 2293 | r = FLD_MOD(r, tclk_trail, 15, 8); |
2206 | r = FLD_MOD(r, tclk_zero, 7, 0); | 2294 | r = FLD_MOD(r, tclk_zero, 7, 0); |
2295 | |||
2296 | if (dss_has_feature(FEAT_DSI_PHY_DCC)) { | ||
2297 | r = FLD_MOD(r, 0, 21, 21); /* DCCEN = disable */ | ||
2298 | r = FLD_MOD(r, 1, 22, 22); /* CLKINP_DIVBY2EN = enable */ | ||
2299 | r = FLD_MOD(r, 1, 23, 23); /* CLKINP_SEL = enable */ | ||
2300 | } | ||
2301 | |||
2207 | dsi_write_reg(dsidev, DSI_DSIPHY_CFG1, r); | 2302 | dsi_write_reg(dsidev, DSI_DSIPHY_CFG1, r); |
2208 | 2303 | ||
2209 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2); | 2304 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2); |
@@ -4188,33 +4283,35 @@ int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev, | |||
4188 | 4283 | ||
4189 | mutex_lock(&dsi->lock); | 4284 | mutex_lock(&dsi->lock); |
4190 | 4285 | ||
4191 | r = dsi_pll_calc_ddrfreq(dsidev, ddr_clk, &cinfo); | 4286 | /* Calculate PLL output clock */ |
4287 | r = dsi_pll_calc_ddrfreq(dsidev, ddr_clk * 4, &cinfo); | ||
4192 | if (r) | 4288 | if (r) |
4193 | goto err; | 4289 | goto err; |
4194 | 4290 | ||
4195 | dssdev->clocks.dsi.regn = cinfo.regn; | 4291 | /* Calculate PLL's DSI clock */ |
4196 | dssdev->clocks.dsi.regm = cinfo.regm; | 4292 | dsi_pll_calc_dsi_fck(dsidev, &cinfo); |
4197 | dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc; | ||
4198 | dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi; | ||
4199 | 4293 | ||
4294 | /* Calculate PLL's DISPC clock and pck & lck divs */ | ||
4295 | pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp; | ||
4296 | DSSDBG("finding dispc dividers for pck %lu\n", pck); | ||
4297 | r = dsi_pll_calc_dispc_fck(dsidev, pck, &cinfo, &dispc_cinfo); | ||
4298 | if (r) | ||
4299 | goto err; | ||
4200 | 4300 | ||
4301 | /* Calculate LP clock */ | ||
4201 | dsi_fclk = cinfo.dsi_pll_hsdiv_dsi_clk; | 4302 | dsi_fclk = cinfo.dsi_pll_hsdiv_dsi_clk; |
4202 | lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk * 2); | 4303 | lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk * 2); |
4203 | 4304 | ||
4204 | dssdev->clocks.dsi.lp_clk_div = lp_clk_div; | 4305 | dssdev->clocks.dsi.regn = cinfo.regn; |
4205 | 4306 | dssdev->clocks.dsi.regm = cinfo.regm; | |
4206 | /* pck = TxByteClkHS * datalanes * 8 / bitsperpixel */ | 4307 | dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc; |
4207 | 4308 | dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi; | |
4208 | pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp; | ||
4209 | |||
4210 | DSSDBG("finding dispc dividers for pck %lu\n", pck); | ||
4211 | 4309 | ||
4212 | dispc_find_clk_divs(pck, cinfo.dsi_pll_hsdiv_dispc_clk, &dispc_cinfo); | 4310 | dssdev->clocks.dsi.lp_clk_div = lp_clk_div; |
4213 | 4311 | ||
4214 | dssdev->clocks.dispc.channel.lck_div = dispc_cinfo.lck_div; | 4312 | dssdev->clocks.dispc.channel.lck_div = dispc_cinfo.lck_div; |
4215 | dssdev->clocks.dispc.channel.pck_div = dispc_cinfo.pck_div; | 4313 | dssdev->clocks.dispc.channel.pck_div = dispc_cinfo.pck_div; |
4216 | 4314 | ||
4217 | |||
4218 | dssdev->clocks.dispc.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK; | 4315 | dssdev->clocks.dispc.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK; |
4219 | 4316 | ||
4220 | dssdev->clocks.dispc.channel.lcd_clk_src = | 4317 | dssdev->clocks.dispc.channel.lcd_clk_src = |
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 759dbee48342..2ab1c3e96553 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c | |||
@@ -69,6 +69,7 @@ struct dss_features { | |||
69 | u8 fck_div_max; | 69 | u8 fck_div_max; |
70 | u8 dss_fck_multiplier; | 70 | u8 dss_fck_multiplier; |
71 | const char *clk_name; | 71 | const char *clk_name; |
72 | int (*dpi_select_source)(enum omap_channel channel); | ||
72 | }; | 73 | }; |
73 | 74 | ||
74 | static struct { | 75 | static struct { |
@@ -99,30 +100,6 @@ static const char * const dss_generic_clk_source_names[] = { | |||
99 | [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK", | 100 | [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK", |
100 | }; | 101 | }; |
101 | 102 | ||
102 | static const struct dss_features omap24xx_dss_feats __initconst = { | ||
103 | .fck_div_max = 16, | ||
104 | .dss_fck_multiplier = 2, | ||
105 | .clk_name = NULL, | ||
106 | }; | ||
107 | |||
108 | static const struct dss_features omap34xx_dss_feats __initconst = { | ||
109 | .fck_div_max = 16, | ||
110 | .dss_fck_multiplier = 2, | ||
111 | .clk_name = "dpll4_m4_ck", | ||
112 | }; | ||
113 | |||
114 | static const struct dss_features omap3630_dss_feats __initconst = { | ||
115 | .fck_div_max = 32, | ||
116 | .dss_fck_multiplier = 1, | ||
117 | .clk_name = "dpll4_m4_ck", | ||
118 | }; | ||
119 | |||
120 | static const struct dss_features omap44xx_dss_feats __initconst = { | ||
121 | .fck_div_max = 32, | ||
122 | .dss_fck_multiplier = 1, | ||
123 | .clk_name = "dpll_per_m5x2_ck", | ||
124 | }; | ||
125 | |||
126 | static inline void dss_write_reg(const struct dss_reg idx, u32 val) | 103 | static inline void dss_write_reg(const struct dss_reg idx, u32 val) |
127 | { | 104 | { |
128 | __raw_writel(val, dss.base + idx.idx); | 105 | __raw_writel(val, dss.base + idx.idx); |
@@ -647,6 +624,65 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void) | |||
647 | return REG_GET(DSS_CONTROL, 15, 15); | 624 | return REG_GET(DSS_CONTROL, 15, 15); |
648 | } | 625 | } |
649 | 626 | ||
627 | static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel) | ||
628 | { | ||
629 | if (channel != OMAP_DSS_CHANNEL_LCD) | ||
630 | return -EINVAL; | ||
631 | |||
632 | return 0; | ||
633 | } | ||
634 | |||
635 | static int dss_dpi_select_source_omap4(enum omap_channel channel) | ||
636 | { | ||
637 | int val; | ||
638 | |||
639 | switch (channel) { | ||
640 | case OMAP_DSS_CHANNEL_LCD2: | ||
641 | val = 0; | ||
642 | break; | ||
643 | case OMAP_DSS_CHANNEL_DIGIT: | ||
644 | val = 1; | ||
645 | break; | ||
646 | default: | ||
647 | return -EINVAL; | ||
648 | } | ||
649 | |||
650 | REG_FLD_MOD(DSS_CONTROL, val, 17, 17); | ||
651 | |||
652 | return 0; | ||
653 | } | ||
654 | |||
655 | static int dss_dpi_select_source_omap5(enum omap_channel channel) | ||
656 | { | ||
657 | int val; | ||
658 | |||
659 | switch (channel) { | ||
660 | case OMAP_DSS_CHANNEL_LCD: | ||
661 | val = 1; | ||
662 | break; | ||
663 | case OMAP_DSS_CHANNEL_LCD2: | ||
664 | val = 2; | ||
665 | break; | ||
666 | case OMAP_DSS_CHANNEL_LCD3: | ||
667 | val = 3; | ||
668 | break; | ||
669 | case OMAP_DSS_CHANNEL_DIGIT: | ||
670 | val = 0; | ||
671 | break; | ||
672 | default: | ||
673 | return -EINVAL; | ||
674 | } | ||
675 | |||
676 | REG_FLD_MOD(DSS_CONTROL, val, 17, 16); | ||
677 | |||
678 | return 0; | ||
679 | } | ||
680 | |||
681 | int dss_dpi_select_source(enum omap_channel channel) | ||
682 | { | ||
683 | return dss.feat->dpi_select_source(channel); | ||
684 | } | ||
685 | |||
650 | static int dss_get_clocks(void) | 686 | static int dss_get_clocks(void) |
651 | { | 687 | { |
652 | struct clk *clk; | 688 | struct clk *clk; |
@@ -721,6 +757,41 @@ void dss_debug_dump_clocks(struct seq_file *s) | |||
721 | } | 757 | } |
722 | #endif | 758 | #endif |
723 | 759 | ||
760 | static const struct dss_features omap24xx_dss_feats __initconst = { | ||
761 | .fck_div_max = 16, | ||
762 | .dss_fck_multiplier = 2, | ||
763 | .clk_name = NULL, | ||
764 | .dpi_select_source = &dss_dpi_select_source_omap2_omap3, | ||
765 | }; | ||
766 | |||
767 | static const struct dss_features omap34xx_dss_feats __initconst = { | ||
768 | .fck_div_max = 16, | ||
769 | .dss_fck_multiplier = 2, | ||
770 | .clk_name = "dpll4_m4_ck", | ||
771 | .dpi_select_source = &dss_dpi_select_source_omap2_omap3, | ||
772 | }; | ||
773 | |||
774 | static const struct dss_features omap3630_dss_feats __initconst = { | ||
775 | .fck_div_max = 32, | ||
776 | .dss_fck_multiplier = 1, | ||
777 | .clk_name = "dpll4_m4_ck", | ||
778 | .dpi_select_source = &dss_dpi_select_source_omap2_omap3, | ||
779 | }; | ||
780 | |||
781 | static const struct dss_features omap44xx_dss_feats __initconst = { | ||
782 | .fck_div_max = 32, | ||
783 | .dss_fck_multiplier = 1, | ||
784 | .clk_name = "dpll_per_m5x2_ck", | ||
785 | .dpi_select_source = &dss_dpi_select_source_omap4, | ||
786 | }; | ||
787 | |||
788 | static const struct dss_features omap54xx_dss_feats __initconst = { | ||
789 | .fck_div_max = 64, | ||
790 | .dss_fck_multiplier = 1, | ||
791 | .clk_name = "dpll_per_h12x2_ck", | ||
792 | .dpi_select_source = &dss_dpi_select_source_omap5, | ||
793 | }; | ||
794 | |||
724 | static int __init dss_init_features(struct device *dev) | 795 | static int __init dss_init_features(struct device *dev) |
725 | { | 796 | { |
726 | const struct dss_features *src; | 797 | const struct dss_features *src; |
@@ -740,6 +811,8 @@ static int __init dss_init_features(struct device *dev) | |||
740 | src = &omap3630_dss_feats; | 811 | src = &omap3630_dss_feats; |
741 | else if (cpu_is_omap44xx()) | 812 | else if (cpu_is_omap44xx()) |
742 | src = &omap44xx_dss_feats; | 813 | src = &omap44xx_dss_feats; |
814 | else if (soc_is_omap54xx()) | ||
815 | src = &omap54xx_dss_feats; | ||
743 | else | 816 | else |
744 | return -ENODEV; | 817 | return -ENODEV; |
745 | 818 | ||
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 417d30571747..40c36cafec6e 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h | |||
@@ -280,6 +280,7 @@ void dss_overlay_kobj_uninit(struct omap_overlay *ovl); | |||
280 | int dss_init_platform_driver(void) __init; | 280 | int dss_init_platform_driver(void) __init; |
281 | void dss_uninit_platform_driver(void); | 281 | void dss_uninit_platform_driver(void); |
282 | 282 | ||
283 | int dss_dpi_select_source(enum omap_channel channel); | ||
283 | void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); | 284 | void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); |
284 | enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); | 285 | enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); |
285 | const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); | 286 | const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); |
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index 47c15304fe87..406913949e2c 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c | |||
@@ -106,6 +106,21 @@ static const struct dss_reg_field omap4_dss_reg_fields[] = { | |||
106 | [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 }, | 106 | [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 }, |
107 | }; | 107 | }; |
108 | 108 | ||
109 | static const struct dss_reg_field omap5_dss_reg_fields[] = { | ||
110 | [FEAT_REG_FIRHINC] = { 12, 0 }, | ||
111 | [FEAT_REG_FIRVINC] = { 28, 16 }, | ||
112 | [FEAT_REG_FIFOLOWTHRESHOLD] = { 15, 0 }, | ||
113 | [FEAT_REG_FIFOHIGHTHRESHOLD] = { 31, 16 }, | ||
114 | [FEAT_REG_FIFOSIZE] = { 15, 0 }, | ||
115 | [FEAT_REG_HORIZONTALACCU] = { 10, 0 }, | ||
116 | [FEAT_REG_VERTICALACCU] = { 26, 16 }, | ||
117 | [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 7 }, | ||
118 | [FEAT_REG_DSIPLL_REGN] = { 8, 1 }, | ||
119 | [FEAT_REG_DSIPLL_REGM] = { 20, 9 }, | ||
120 | [FEAT_REG_DSIPLL_REGM_DISPC] = { 25, 21 }, | ||
121 | [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 }, | ||
122 | }; | ||
123 | |||
109 | static const enum omap_display_type omap2_dss_supported_displays[] = { | 124 | static const enum omap_display_type omap2_dss_supported_displays[] = { |
110 | /* OMAP_DSS_CHANNEL_LCD */ | 125 | /* OMAP_DSS_CHANNEL_LCD */ |
111 | OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI, | 126 | OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI, |
@@ -144,6 +159,19 @@ static const enum omap_display_type omap4_dss_supported_displays[] = { | |||
144 | OMAP_DISPLAY_TYPE_DSI, | 159 | OMAP_DISPLAY_TYPE_DSI, |
145 | }; | 160 | }; |
146 | 161 | ||
162 | static const enum omap_display_type omap5_dss_supported_displays[] = { | ||
163 | /* OMAP_DSS_CHANNEL_LCD */ | ||
164 | OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | | ||
165 | OMAP_DISPLAY_TYPE_DSI, | ||
166 | |||
167 | /* OMAP_DSS_CHANNEL_DIGIT */ | ||
168 | OMAP_DISPLAY_TYPE_HDMI | OMAP_DISPLAY_TYPE_DPI, | ||
169 | |||
170 | /* OMAP_DSS_CHANNEL_LCD2 */ | ||
171 | OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | | ||
172 | OMAP_DISPLAY_TYPE_DSI, | ||
173 | }; | ||
174 | |||
147 | static const enum omap_color_mode omap2_dss_supported_color_modes[] = { | 175 | static const enum omap_color_mode omap2_dss_supported_color_modes[] = { |
148 | /* OMAP_DSS_GFX */ | 176 | /* OMAP_DSS_GFX */ |
149 | OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 | | 177 | OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 | |
@@ -298,6 +326,14 @@ static const char * const omap4_dss_clk_source_names[] = { | |||
298 | [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "PLL2_CLK2", | 326 | [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "PLL2_CLK2", |
299 | }; | 327 | }; |
300 | 328 | ||
329 | static const char * const omap5_dss_clk_source_names[] = { | ||
330 | [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DPLL_DSI1_A_CLK1", | ||
331 | [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DPLL_DSI1_A_CLK2", | ||
332 | [OMAP_DSS_CLK_SRC_FCK] = "DSS_CLK", | ||
333 | [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DPLL_DSI1_C_CLK1", | ||
334 | [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DPLL_DSI1_C_CLK2", | ||
335 | }; | ||
336 | |||
301 | static const struct dss_param_range omap2_dss_param_range[] = { | 337 | static const struct dss_param_range omap2_dss_param_range[] = { |
302 | [FEAT_PARAM_DSS_FCK] = { 0, 173000000 }, | 338 | [FEAT_PARAM_DSS_FCK] = { 0, 173000000 }, |
303 | [FEAT_PARAM_DSS_PCD] = { 2, 255 }, | 339 | [FEAT_PARAM_DSS_PCD] = { 2, 255 }, |
@@ -349,6 +385,22 @@ static const struct dss_param_range omap4_dss_param_range[] = { | |||
349 | [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 }, | 385 | [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 }, |
350 | }; | 386 | }; |
351 | 387 | ||
388 | static const struct dss_param_range omap5_dss_param_range[] = { | ||
389 | [FEAT_PARAM_DSS_FCK] = { 0, 200000000 }, | ||
390 | [FEAT_PARAM_DSS_PCD] = { 1, 255 }, | ||
391 | [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 }, | ||
392 | [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 }, | ||
393 | [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 }, | ||
394 | [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 }, | ||
395 | [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 }, | ||
396 | [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, | ||
397 | [FEAT_PARAM_DSI_FCK] = { 0, 170000000 }, | ||
398 | [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, | ||
399 | [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, | ||
400 | [FEAT_PARAM_MGR_WIDTH] = { 1, 2048 }, | ||
401 | [FEAT_PARAM_MGR_HEIGHT] = { 1, 2048 }, | ||
402 | }; | ||
403 | |||
352 | static const enum dss_feat_id omap2_dss_feat_list[] = { | 404 | static const enum dss_feat_id omap2_dss_feat_list[] = { |
353 | FEAT_LCDENABLEPOL, | 405 | FEAT_LCDENABLEPOL, |
354 | FEAT_LCDENABLESIGNAL, | 406 | FEAT_LCDENABLESIGNAL, |
@@ -469,6 +521,28 @@ static const enum dss_feat_id omap4_dss_feat_list[] = { | |||
469 | FEAT_BURST_2D, | 521 | FEAT_BURST_2D, |
470 | }; | 522 | }; |
471 | 523 | ||
524 | static const enum dss_feat_id omap5_dss_feat_list[] = { | ||
525 | FEAT_MGR_LCD2, | ||
526 | FEAT_CORE_CLK_DIV, | ||
527 | FEAT_LCD_CLK_SRC, | ||
528 | FEAT_DSI_DCS_CMD_CONFIG_VC, | ||
529 | FEAT_DSI_VC_OCP_WIDTH, | ||
530 | FEAT_DSI_GNQ, | ||
531 | FEAT_HDMI_CTS_SWMODE, | ||
532 | FEAT_HDMI_AUDIO_USE_MCLK, | ||
533 | FEAT_HANDLE_UV_SEPARATE, | ||
534 | FEAT_ATTR2, | ||
535 | FEAT_CPR, | ||
536 | FEAT_PRELOAD, | ||
537 | FEAT_FIR_COEF_V, | ||
538 | FEAT_ALPHA_FREE_ZORDER, | ||
539 | FEAT_FIFO_MERGE, | ||
540 | FEAT_BURST_2D, | ||
541 | FEAT_DSI_PLL_SELFREQDCO, | ||
542 | FEAT_DSI_PLL_REFSEL, | ||
543 | FEAT_DSI_PHY_DCC, | ||
544 | }; | ||
545 | |||
472 | /* OMAP2 DSS Features */ | 546 | /* OMAP2 DSS Features */ |
473 | static const struct omap_dss_features omap2_dss_features = { | 547 | static const struct omap_dss_features omap2_dss_features = { |
474 | .reg_fields = omap2_dss_reg_fields, | 548 | .reg_fields = omap2_dss_reg_fields, |
@@ -612,6 +686,26 @@ static const struct omap_dss_features omap4_dss_features = { | |||
612 | .burst_size_unit = 16, | 686 | .burst_size_unit = 16, |
613 | }; | 687 | }; |
614 | 688 | ||
689 | /* OMAP5 DSS Features */ | ||
690 | static const struct omap_dss_features omap5_dss_features = { | ||
691 | .reg_fields = omap5_dss_reg_fields, | ||
692 | .num_reg_fields = ARRAY_SIZE(omap5_dss_reg_fields), | ||
693 | |||
694 | .features = omap5_dss_feat_list, | ||
695 | .num_features = ARRAY_SIZE(omap5_dss_feat_list), | ||
696 | |||
697 | .num_mgrs = 3, | ||
698 | .num_ovls = 4, | ||
699 | .supported_displays = omap5_dss_supported_displays, | ||
700 | .supported_color_modes = omap4_dss_supported_color_modes, | ||
701 | .overlay_caps = omap4_dss_overlay_caps, | ||
702 | .clksrc_names = omap5_dss_clk_source_names, | ||
703 | .dss_params = omap5_dss_param_range, | ||
704 | .supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER, | ||
705 | .buffer_size_unit = 16, | ||
706 | .burst_size_unit = 16, | ||
707 | }; | ||
708 | |||
615 | #if defined(CONFIG_OMAP4_DSS_HDMI) | 709 | #if defined(CONFIG_OMAP4_DSS_HDMI) |
616 | /* HDMI OMAP4 Functions*/ | 710 | /* HDMI OMAP4 Functions*/ |
617 | static const struct ti_hdmi_ip_ops omap4_hdmi_functions = { | 711 | static const struct ti_hdmi_ip_ops omap4_hdmi_functions = { |
@@ -754,6 +848,8 @@ void dss_features_init(void) | |||
754 | omap_current_dss_features = &omap4430_es2_0_1_2_dss_features; | 848 | omap_current_dss_features = &omap4430_es2_0_1_2_dss_features; |
755 | else if (cpu_is_omap44xx()) | 849 | else if (cpu_is_omap44xx()) |
756 | omap_current_dss_features = &omap4_dss_features; | 850 | omap_current_dss_features = &omap4_dss_features; |
851 | else if (soc_is_omap54xx()) | ||
852 | omap_current_dss_features = &omap5_dss_features; | ||
757 | else | 853 | else |
758 | DSSWARN("Unsupported OMAP version"); | 854 | DSSWARN("Unsupported OMAP version"); |
759 | } | 855 | } |
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index b81d603310a8..aacad863fa22 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h | |||
@@ -65,6 +65,9 @@ enum dss_feat_id { | |||
65 | /* An unknown HW bug causing the normal FIFO thresholds not to work */ | 65 | /* An unknown HW bug causing the normal FIFO thresholds not to work */ |
66 | FEAT_OMAP3_DSI_FIFO_BUG, | 66 | FEAT_OMAP3_DSI_FIFO_BUG, |
67 | FEAT_BURST_2D, | 67 | FEAT_BURST_2D, |
68 | FEAT_DSI_PLL_SELFREQDCO, | ||
69 | FEAT_DSI_PLL_REFSEL, | ||
70 | FEAT_DSI_PHY_DCC, | ||
68 | }; | 71 | }; |
69 | 72 | ||
70 | /* DSS register field id */ | 73 | /* DSS register field id */ |