aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/omap2/displays/panel-taal.c6
-rw-r--r--drivers/video/omap2/dss/dsi.c126
2 files changed, 132 insertions, 0 deletions
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 77aed0e51f9b..ddda96a52d06 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1065,6 +1065,12 @@ static int taal_power_on(struct omap_dss_device *dssdev)
1065 omapdss_dsi_set_pixel_format(dssdev, OMAP_DSS_DSI_FMT_RGB888); 1065 omapdss_dsi_set_pixel_format(dssdev, OMAP_DSS_DSI_FMT_RGB888);
1066 omapdss_dsi_set_operation_mode(dssdev, OMAP_DSS_DSI_CMD_MODE); 1066 omapdss_dsi_set_operation_mode(dssdev, OMAP_DSS_DSI_CMD_MODE);
1067 1067
1068 r = omapdss_dsi_set_clocks(dssdev, 216000000, 10000000);
1069 if (r) {
1070 dev_err(&dssdev->dev, "failed to set HS and LP clocks\n");
1071 goto err0;
1072 }
1073
1068 r = omapdss_dsi_display_enable(dssdev); 1074 r = omapdss_dsi_display_enable(dssdev);
1069 if (r) { 1075 if (r) {
1070 dev_err(&dssdev->dev, "failed to enable DSI\n"); 1076 dev_err(&dssdev->dev, "failed to enable DSI\n");
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 96d0024ada40..340c832d21d8 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -1454,6 +1454,68 @@ found:
1454 return 0; 1454 return 0;
1455} 1455}
1456 1456
1457static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev,
1458 unsigned long req_clk, struct dsi_clock_info *cinfo)
1459{
1460 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1461 struct dsi_clock_info cur, best;
1462 unsigned long dss_sys_clk, max_dss_fck, max_dsi_fck;
1463 unsigned long req_clkin4ddr;
1464
1465 DSSDBG("dsi_pll_calc_ddrfreq\n");
1466
1467 dss_sys_clk = clk_get_rate(dsi->sys_clk);
1468
1469 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
1470 max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK);
1471
1472 memset(&best, 0, sizeof(best));
1473 memset(&cur, 0, sizeof(cur));
1474
1475 cur.clkin = dss_sys_clk;
1476
1477 req_clkin4ddr = req_clk * 4;
1478
1479 for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) {
1480 cur.fint = cur.clkin / cur.regn;
1481
1482 if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min)
1483 continue;
1484
1485 /* DSIPHY(MHz) = (2 * regm / regn) * clkin */
1486 for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) {
1487 unsigned long a, b;
1488
1489 a = 2 * cur.regm * (cur.clkin/1000);
1490 b = cur.regn;
1491 cur.clkin4ddr = a / b * 1000;
1492
1493 if (cur.clkin4ddr > 1800 * 1000 * 1000)
1494 break;
1495
1496 if (abs(cur.clkin4ddr - req_clkin4ddr) <
1497 abs(best.clkin4ddr - req_clkin4ddr)) {
1498 best = cur;
1499 DSSDBG("best %ld\n", best.clkin4ddr);
1500 }
1501
1502 if (cur.clkin4ddr == req_clkin4ddr)
1503 goto found;
1504 }
1505 }
1506found:
1507 best.regm_dispc = DIV_ROUND_UP(best.clkin4ddr, max_dss_fck);
1508 best.dsi_pll_hsdiv_dispc_clk = best.clkin4ddr / best.regm_dispc;
1509
1510 best.regm_dsi = DIV_ROUND_UP(best.clkin4ddr, max_dsi_fck);
1511 best.dsi_pll_hsdiv_dsi_clk = best.clkin4ddr / best.regm_dsi;
1512
1513 if (cinfo)
1514 *cinfo = best;
1515
1516 return 0;
1517}
1518
1457int dsi_pll_set_clock_div(struct platform_device *dsidev, 1519int dsi_pll_set_clock_div(struct platform_device *dsidev,
1458 struct dsi_clock_info *cinfo) 1520 struct dsi_clock_info *cinfo)
1459{ 1521{
@@ -4110,6 +4172,70 @@ int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
4110} 4172}
4111EXPORT_SYMBOL(omapdss_dsi_configure_pins); 4173EXPORT_SYMBOL(omapdss_dsi_configure_pins);
4112 4174
4175int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
4176 unsigned long ddr_clk, unsigned long lp_clk)
4177{
4178 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4179 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4180 struct dsi_clock_info cinfo;
4181 struct dispc_clock_info dispc_cinfo;
4182 unsigned lp_clk_div;
4183 unsigned long dsi_fclk;
4184 int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
4185 unsigned long pck;
4186 int r;
4187
4188 DSSDBGF("ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);
4189
4190 mutex_lock(&dsi->lock);
4191
4192 r = dsi_pll_calc_ddrfreq(dsidev, ddr_clk, &cinfo);
4193 if (r)
4194 goto err;
4195
4196 dssdev->clocks.dsi.regn = cinfo.regn;
4197 dssdev->clocks.dsi.regm = cinfo.regm;
4198 dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc;
4199 dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi;
4200
4201
4202 dsi_fclk = cinfo.dsi_pll_hsdiv_dsi_clk;
4203 lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk * 2);
4204
4205 dssdev->clocks.dsi.lp_clk_div = lp_clk_div;
4206
4207 /* pck = TxByteClkHS * datalanes * 8 / bitsperpixel */
4208
4209 pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp;
4210
4211 DSSDBG("finding dispc dividers for pck %lu\n", pck);
4212
4213 dispc_find_clk_divs(pck, cinfo.dsi_pll_hsdiv_dispc_clk, &dispc_cinfo);
4214
4215 dssdev->clocks.dispc.channel.lck_div = dispc_cinfo.lck_div;
4216 dssdev->clocks.dispc.channel.pck_div = dispc_cinfo.pck_div;
4217
4218
4219 dssdev->clocks.dispc.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK;
4220
4221 dssdev->clocks.dispc.channel.lcd_clk_src =
4222 dsi->module_id == 0 ?
4223 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
4224 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
4225
4226 dssdev->clocks.dsi.dsi_fclk_src =
4227 dsi->module_id == 0 ?
4228 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
4229 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI;
4230
4231 mutex_unlock(&dsi->lock);
4232 return 0;
4233err:
4234 mutex_unlock(&dsi->lock);
4235 return r;
4236}
4237EXPORT_SYMBOL(omapdss_dsi_set_clocks);
4238
4113int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) 4239int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
4114{ 4240{
4115 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4241 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);