]> git.sur5r.net Git - u-boot/blobdiff - arch/arm/mach-tegra/clock.c
arm: freescale: Rename initdram() to fsl_initdram()
[u-boot] / arch / arm / mach-tegra / clock.c
index cf8bc38925d200cbcd49416a926e4481e73aa4d1..3bb72331a4290b68916a3990aa73868a93b4ae87 100644 (file)
@@ -311,9 +311,43 @@ unsigned long clock_get_periph_rate(enum periph_id periph_id,
                enum clock_id parent)
 {
        u32 *reg = get_periph_source_reg(periph_id);
+       unsigned parent_rate = pll_rate[parent];
+       int div = (readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT;
+
+       switch (periph_id) {
+       case PERIPH_ID_UART1:
+       case PERIPH_ID_UART2:
+       case PERIPH_ID_UART3:
+       case PERIPH_ID_UART4:
+       case PERIPH_ID_UART5:
+#ifdef CONFIG_TEGRA20
+               /* There's no divider for these clocks in this SoC. */
+               return parent_rate;
+#else
+               /*
+                * This undoes the +2 in get_rate_from_divider() which I
+                * believe is incorrect. Ideally we would fix
+                * get_rate_from_divider(), but... Removing the +2 from
+                * get_rate_from_divider() would probably require remove the -2
+                * from the tail of clk_get_divider() since I believe that's
+                * only there to invert get_rate_from_divider()'s +2. Observe
+                * how find_best_divider() uses those two functions together.
+                * However, doing so breaks other stuff, such as Seaboard's
+                * display, likely due to clock_set_pllout()'s call to
+                * clk_get_divider(). Attempting to fix that by making
+                * clock_set_pllout() subtract 2 from clk_get_divider()'s
+                * return value doesn't help. In summary this clock driver is
+                * quite broken but I'm afraid I have no idea how to fix it
+                * without completely replacing it.
+                */
+               div -= 2;
+               break;
+#endif
+       default:
+               break;
+       }
 
-       return get_rate_from_divider(pll_rate[parent],
-               (readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT);
+       return get_rate_from_divider(parent_rate, div);
 }
 
 /**