aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2013-03-05 09:34:05 -0500
committerTomi Valkeinen <tomi.valkeinen@ti.com>2013-04-03 08:19:17 -0400
commit43417823fd8210edb7e714bea82ea9bd77089635 (patch)
treeff0679cce0ad56cab87a047897aab236371e1f49
parent7c284e6ee3710e96bf246e6b52032f3d766fa094 (diff)
OMAPDSS: DSS: add new clock calculation code
Add new way to iterate over DSS clock divisors. dss_div_calc() provides a generic way to go over all the divisors, within given clock range. dss_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/dss.c39
-rw-r--r--drivers/video/omap2/dss/dss.h3
2 files changed, 42 insertions, 0 deletions
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 054c2a22b3f1..eba4127b61a6 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -473,6 +473,45 @@ int dss_calc_clock_rates(struct dss_clock_info *cinfo)
473 return 0; 473 return 0;
474} 474}
475 475
476bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data)
477{
478 int fckd, fckd_start, fckd_stop;
479 unsigned long fck;
480 unsigned long fck_hw_max;
481 unsigned long fckd_hw_max;
482 unsigned long prate;
483
484 if (dss.dpll4_m4_ck == NULL) {
485 /*
486 * TODO: dss1_fclk can be changed on OMAP2, but the available
487 * dividers are not continuous. We just use the pre-set rate for
488 * now.
489 */
490 fck = clk_get_rate(dss.dss_clk);
491 fckd = 1;
492 return func(fckd, fck, data);
493 }
494
495 fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
496 fckd_hw_max = dss.feat->fck_div_max;
497
498 prate = dss_get_dpll4_rate() * dss.feat->dss_fck_multiplier;
499
500 fck_min = fck_min ? fck_min : 1;
501
502 fckd_start = min(prate / fck_min, fckd_hw_max);
503 fckd_stop = max(DIV_ROUND_UP(prate, fck_hw_max), 1ul);
504
505 for (fckd = fckd_start; fckd >= fckd_stop; --fckd) {
506 fck = prate / fckd;
507
508 if (func(fckd, fck, data))
509 return true;
510 }
511
512 return false;
513}
514
476int dss_set_clock_div(struct dss_clock_info *cinfo) 515int dss_set_clock_div(struct dss_clock_info *cinfo)
477{ 516{
478 if (dss.dpll4_m4_ck) { 517 if (dss.dpll4_m4_ck) {
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 0ff41dd8f3c5..4180302a7fb3 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -271,6 +271,9 @@ int dss_set_clock_div(struct dss_clock_info *cinfo);
271int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo, 271int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
272 struct dispc_clock_info *dispc_cinfo); 272 struct dispc_clock_info *dispc_cinfo);
273 273
274typedef bool (*dss_div_calc_func)(int fckd, unsigned long fck, void *data);
275bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data);
276
274/* SDI */ 277/* SDI */
275int sdi_init_platform_driver(void) __init; 278int sdi_init_platform_driver(void) __init;
276void sdi_uninit_platform_driver(void) __exit; 279void sdi_uninit_platform_driver(void) __exit;