]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
omap2 clock: convert omap2_clksel_round_rate to use new clksel struct
authorPaul Walmsley <paul@pwsan.com>
Mon, 27 Aug 2007 08:39:05 +0000 (02:39 -0600)
committerTony Lindgren <tony@atomide.com>
Fri, 31 Aug 2007 18:10:35 +0000 (11:10 -0700)
Convert omap2_clksel_round_rate() to use the new clksel struct data.

Signed-off-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
arch/arm/mach-omap2/clock.c

index 3c5d37358f108fc54d62d210e0d5f12da913df03..ec543e147006d4f82a3114d4410862e8881d3bac 100644 (file)
@@ -87,8 +87,6 @@ static struct clk *vclk;
 static struct clk *sclk;
 static u8 cpu_mask;
 
-static u32 sysclkout_div[] = {1, 2, 4, 8, 16};
-
 /*-------------------------------------------------------------------------
  * Omap2 specific clock functions
  *-------------------------------------------------------------------------*/
@@ -530,62 +528,66 @@ const static struct clksel *omap2_get_clksel_by_parent(struct clk *clk,
        return clks;
 }
 
-/*
- * Find divisor for the given clock and target rate.
+/**
+ * omap2_clksel_round_rate - find divisor for the given clock and target rate.
+ * @clk: OMAP struct clk to use
+ * @target_rate: desired clock rate
+ * @new_div: ptr to where we should store the divisor
  *
+ * Finds 'best' divider value in an array based on the source and target
+ * rates.  The divider array must be sorted with smallest divider first.
  * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
  * they are only settable as part of virtual_prcm set.
+ *
+ * Returns the rounded clock rate or returns 0xffffffff on error.
  */
-static u32 omap2_clksel_round_rate(struct clk *tclk, u32 target_rate,
-       u32 *new_div)
+static u32 omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate,
+                                  u32 *new_div)
 {
-       u32 gfx_div[] = {2, 3, 4};
-       u32 dss1_div[] = {1, 2, 3, 4, 5, 6, 8, 9, 12, 16};
-       u32 vlynq_div[] = {1, 2, 3, 4, 6, 8, 9, 12, 16, 18};
-       u32 best_div = ~0, asize = 0;
-       u32 *div_array = NULL;
+       unsigned long test_rate;
+       const struct clksel *clks;
+       const struct clksel_rate *clkr;
+       u32 last_div = 0;
 
-       switch (tclk->flags & SRC_RATE_SEL_MASK) {
-       case CM_GFX_SEL1:
-               asize = ARRAY_SIZE(gfx_div);
-               div_array = gfx_div;
-               break;
-       case CM_PLL_SEL1:
-               return omap2_dpll_round_rate(target_rate);
-       case CM_SYSCLKOUT_SEL1:
-               asize = ARRAY_SIZE(sysclkout_div);
-               div_array = sysclkout_div;
-               break;
-       case CM_CORE_SEL1:
-               if (tclk == &dss1_fck) {
-                       if (tclk->parent == &core_ck) {
-                               asize = ARRAY_SIZE(dss1_div);
-                               div_array = dss1_div;
-                       } else {
-                               *new_div = 0; /* fixed clk */
-                               return(tclk->parent->rate);
-                       }
-               } else if ((tclk == &vlynq_fck) && cpu_is_omap2420()) {
-                       if (tclk->parent == &core_ck) {
-                               asize = ARRAY_SIZE(vlynq_div);
-                               div_array = vlynq_div;
-                       } else {
-                               *new_div = 0; /* fixed clk */
-                               return (tclk->parent->rate);
-                       }
-               }
-               break;
+       printk(KERN_INFO "clock: clksel_round_rate for %s target_rate %ld\n",
+              clk->name, target_rate);
+
+       *new_div = 1;
+
+       clks = omap2_get_clksel_by_parent(clk, clk->parent);
+       if (clks == NULL)
+               return ~0;
+
+       for (clkr = clks->rates; clkr->div; clkr++) {
+               if (!(clkr->flags & cpu_mask))
+                   continue;
+
+               /* Sanity check */
+               if (clkr->div <= last_div)
+                       printk(KERN_ERR "clock: clksel_rate table not sorted "
+                              "for clock %s", clk->name);
+
+               last_div = clkr->div;
+
+               test_rate = clk->parent->rate / clkr->div;
+
+               if (test_rate <= target_rate)
+                       break; /* found it */
        }
 
-       best_div = omap2_divider_from_table(asize, div_array,
-                                           tclk->parent->rate, target_rate);
-       if (best_div == ~0) {
-               *new_div = 1;
-               return best_div; /* signal error */
+       if (!clkr->div) {
+               printk(KERN_ERR "clock: Could not find divisor for target "
+                      "rate %ld for clock %s parent %s\n", target_rate,
+                      clk->name, clk->parent->name);
+               return ~0;
        }
 
-       *new_div = best_div;
-       return (tclk->parent->rate / best_div);
+       *new_div = clkr->div;
+
+       printk(KERN_INFO "clock: new_div = %d, new_rate = %ld\n", *new_div,
+              (clk->parent->rate / clkr->div));
+
+       return (clk->parent->rate / clkr->div);
 }
 
 /* Given a clock and a rate apply a clock specific rounding function */