aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2012-09-25 04:26:28 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2012-09-25 04:26:28 -0400
commit406f7b8baa8f92d88dac448a9dc0dbeb3e330874 (patch)
tree9abc90f8338cb2c886e263d64a1d6fe8f389ee3d /drivers/video
parentc0ca7c38c5d35c12a9b94ef42842b325dfd2a3cd (diff)
parent995885897ff0ef3dad12fcfbfd0c26e185bf4ac0 (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/Kconfig2
-rw-r--r--drivers/video/omap2/dss/dispc.c2
-rw-r--r--drivers/video/omap2/dss/dpi.c5
-rw-r--r--drivers/video/omap2/dss/dsi.c167
-rw-r--r--drivers/video/omap2/dss/dss.c121
-rw-r--r--drivers/video/omap2/dss/dss.h1
-rw-r--r--drivers/video/omap2/dss/dss_features.c96
-rw-r--r--drivers/video/omap2/dss/dss_features.h3
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
85config OMAP2_DSS_DSI 85config 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);
239err_get_dsi: 243err_get_dsi:
244err_src_sel:
240 dispc_runtime_put(); 245 dispc_runtime_put();
241err_get_dispc: 246err_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
1456static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev, 1456static 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 }
1505found: 1496found:
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
1503static 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
1514static 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
1538retry:
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 }
1589found:
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
1518int dsi_pll_set_clock_div(struct platform_device *dsidev, 1598int 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
74static struct { 75static 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
102static const struct dss_features omap24xx_dss_feats __initconst = {
103 .fck_div_max = 16,
104 .dss_fck_multiplier = 2,
105 .clk_name = NULL,
106};
107
108static 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
114static 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
120static 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
126static inline void dss_write_reg(const struct dss_reg idx, u32 val) 103static 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
627static 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
635static 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
655static 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
681int dss_dpi_select_source(enum omap_channel channel)
682{
683 return dss.feat->dpi_select_source(channel);
684}
685
650static int dss_get_clocks(void) 686static 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
760static 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
767static 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
774static 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
781static 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
788static 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
724static int __init dss_init_features(struct device *dev) 795static 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);
280int dss_init_platform_driver(void) __init; 280int dss_init_platform_driver(void) __init;
281void dss_uninit_platform_driver(void); 281void dss_uninit_platform_driver(void);
282 282
283int dss_dpi_select_source(enum omap_channel channel);
283void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); 284void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
284enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); 285enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
285const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); 286const 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
109static 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
109static const enum omap_display_type omap2_dss_supported_displays[] = { 124static 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
162static 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
147static const enum omap_color_mode omap2_dss_supported_color_modes[] = { 175static 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
329static 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
301static const struct dss_param_range omap2_dss_param_range[] = { 337static 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
388static 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
352static const enum dss_feat_id omap2_dss_feat_list[] = { 404static 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
524static 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 */
473static const struct omap_dss_features omap2_dss_features = { 547static 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 */
690static 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*/
617static const struct ti_hdmi_ip_ops omap4_hdmi_functions = { 711static 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 */