aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2013-03-05 09:32:08 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2013-04-03 08:19:17 -0400
commit7c284e6ee3710e96bf246e6b52032f3d766fa094 (patch)
treea713a5d43b0920912a66d666dd8e786704513a6a
parent4ce9e33c0f6abc4203f25f5fc287bf072de32513 (diff)
OMAPDSS: DISPC: add new clock calculation code
Add new way to iterate over DISPC clock divisors. dispc_div_calc() provides a generic way to go over all the divisors, within given pixel clock range. dispc_div_calc() will call a callback function for each divider set, making the function reusable for all use cases. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
-rw-r--r--drivers/video/omap2/dss/dispc.c60
-rw-r--r--drivers/video/omap2/dss/dss.h6
2 files changed, 66 insertions, 0 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index f564955ddd9e..cd54e8fe2d58 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -3374,6 +3374,66 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
3374 return 0; 3374 return 0;
3375} 3375}
3376 3376
3377bool dispc_div_calc(unsigned long dispc,
3378 unsigned long pck_min, unsigned long pck_max,
3379 dispc_div_calc_func func, void *data)
3380{
3381 int lckd, lckd_start, lckd_stop;
3382 int pckd, pckd_start, pckd_stop;
3383 unsigned long pck, lck;
3384 unsigned long lck_max;
3385 unsigned long pckd_hw_min, pckd_hw_max;
3386 unsigned min_fck_per_pck;
3387 unsigned long fck;
3388
3389#ifdef CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK
3390 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
3391#else
3392 min_fck_per_pck = 0;
3393#endif
3394
3395 pckd_hw_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD);
3396 pckd_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD);
3397
3398 lck_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
3399
3400 pck_min = pck_min ? pck_min : 1;
3401 pck_max = pck_max ? pck_max : ULONG_MAX;
3402
3403 lckd_start = max(DIV_ROUND_UP(dispc, lck_max), 1ul);
3404 lckd_stop = min(dispc / pck_min, 255ul);
3405
3406 for (lckd = lckd_start; lckd <= lckd_stop; ++lckd) {
3407 lck = dispc / lckd;
3408
3409 pckd_start = max(DIV_ROUND_UP(lck, pck_max), pckd_hw_min);
3410 pckd_stop = min(lck / pck_min, pckd_hw_max);
3411
3412 for (pckd = pckd_start; pckd <= pckd_stop; ++pckd) {
3413 pck = lck / pckd;
3414
3415 /*
3416 * For OMAP2/3 the DISPC fclk is the same as LCD's logic
3417 * clock, which means we're configuring DISPC fclk here
3418 * also. Thus we need to use the calculated lck. For
3419 * OMAP4+ the DISPC fclk is a separate clock.
3420 */
3421 if (dss_has_feature(FEAT_CORE_CLK_DIV))
3422 fck = dispc_core_clk_rate();
3423 else
3424 fck = lck;
3425
3426 if (fck < pck * min_fck_per_pck)
3427 continue;
3428
3429 if (func(lckd, pckd, lck, pck, data))
3430 return true;
3431 }
3432 }
3433
3434 return false;
3435}
3436
3377void dispc_mgr_set_clock_div(enum omap_channel channel, 3437void dispc_mgr_set_clock_div(enum omap_channel channel,
3378 const struct dispc_clock_info *cinfo) 3438 const struct dispc_clock_info *cinfo)
3379{ 3439{
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 610c8e563daa..0ff41dd8f3c5 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -376,6 +376,12 @@ void dispc_enable_fifomerge(bool enable);
376void dispc_enable_gamma_table(bool enable); 376void dispc_enable_gamma_table(bool enable);
377void dispc_set_loadmode(enum omap_dss_load_mode mode); 377void dispc_set_loadmode(enum omap_dss_load_mode mode);
378 378
379typedef bool (*dispc_div_calc_func)(int lckd, int pckd, unsigned long lck,
380 unsigned long pck, void *data);
381bool dispc_div_calc(unsigned long dispc,
382 unsigned long pck_min, unsigned long pck_max,
383 dispc_div_calc_func func, void *data);
384
379bool dispc_mgr_timings_ok(enum omap_channel channel, 385bool dispc_mgr_timings_ok(enum omap_channel channel,
380 const struct omap_video_timings *timings); 386 const struct omap_video_timings *timings);
381unsigned long dispc_fclk_rate(void); 387unsigned long dispc_fclk_rate(void);