diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/omap2/displays/panel-taal.c | 6 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 126 |
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 | ||
1457 | static 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 | } | ||
1506 | found: | ||
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 | |||
1457 | int dsi_pll_set_clock_div(struct platform_device *dsidev, | 1519 | int 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 | } |
4111 | EXPORT_SYMBOL(omapdss_dsi_configure_pins); | 4173 | EXPORT_SYMBOL(omapdss_dsi_configure_pins); |
4112 | 4174 | ||
4175 | int 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; | ||
4233 | err: | ||
4234 | mutex_unlock(&dsi->lock); | ||
4235 | return r; | ||
4236 | } | ||
4237 | EXPORT_SYMBOL(omapdss_dsi_set_clocks); | ||
4238 | |||
4113 | int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) | 4239 | int 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); |