aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2013-03-05 10:06:26 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2013-04-03 08:19:18 -0400
commit36816faadff37ac7d29be20471d37a2b938ece5d (patch)
treeb6b791f47f79d16ea5f14cdca21b1daff02be773
parent72658f0716f36efad19d37517456b4a8a7cc7840 (diff)
OMAPDSS: SDI: use new clock calculation code
Use the new clock calculation code in the SDI driver. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
-rw-r--r--drivers/video/omap2/dss/sdi.c68
1 files changed, 67 insertions, 1 deletions
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 3888cfa0881c..e6baee2e84f8 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -41,6 +41,72 @@ static struct {
41 struct omap_dss_output output; 41 struct omap_dss_output output;
42} sdi; 42} sdi;
43 43
44struct sdi_clk_calc_ctx {
45 unsigned long pck_min, pck_max;
46
47 struct dss_clock_info dss_cinfo;
48 struct dispc_clock_info dispc_cinfo;
49};
50
51static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
52 unsigned long pck, void *data)
53{
54 struct sdi_clk_calc_ctx *ctx = data;
55
56 ctx->dispc_cinfo.lck_div = lckd;
57 ctx->dispc_cinfo.pck_div = pckd;
58 ctx->dispc_cinfo.lck = lck;
59 ctx->dispc_cinfo.pck = pck;
60
61 return true;
62}
63
64static bool dpi_calc_dss_cb(int fckd, unsigned long fck, void *data)
65{
66 struct sdi_clk_calc_ctx *ctx = data;
67
68 ctx->dss_cinfo.fck = fck;
69 ctx->dss_cinfo.fck_div = fckd;
70
71 return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max,
72 dpi_calc_dispc_cb, ctx);
73}
74
75static int sdi_calc_clock_div(unsigned long pclk,
76 struct dss_clock_info *dss_cinfo,
77 struct dispc_clock_info *dispc_cinfo)
78{
79 int i;
80 struct sdi_clk_calc_ctx ctx;
81
82 /*
83 * DSS fclk gives us very few possibilities, so finding a good pixel
84 * clock may not be possible. We try multiple times to find the clock,
85 * each time widening the pixel clock range we look for, up to
86 * +/- 1MHz.
87 */
88
89 for (i = 0; i < 10; ++i) {
90 bool ok;
91
92 memset(&ctx, 0, sizeof(ctx));
93 if (pclk > 1000 * i * i * i)
94 ctx.pck_min = max(pclk - 1000 * i * i * i, 0lu);
95 else
96 ctx.pck_min = 0;
97 ctx.pck_max = pclk + 1000 * i * i * i;
98
99 ok = dss_div_calc(ctx.pck_min, dpi_calc_dss_cb, &ctx);
100 if (ok) {
101 *dss_cinfo = ctx.dss_cinfo;
102 *dispc_cinfo = ctx.dispc_cinfo;
103 return 0;
104 }
105 }
106
107 return -EINVAL;
108}
109
44static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) 110static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
45{ 111{
46 struct omap_overlay_manager *mgr = dssdev->output->manager; 112 struct omap_overlay_manager *mgr = dssdev->output->manager;
@@ -88,7 +154,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
88 t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; 154 t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
89 t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; 155 t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
90 156
91 r = dss_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo); 157 r = sdi_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo);
92 if (r) 158 if (r)
93 goto err_calc_clock_div; 159 goto err_calc_clock_div;
94 160